AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
566 :
567 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
568 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
570{
572 m_skipCheck = skipCheck;
573 m_selfContainer = nullptr;
575 m_executedCurrently = false;
578 m_comboTarget = nullptr;
579 m_delayStart = 0;
581
583 m_auraScaleMask = 0;
584 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
585
586 // Get data for type of attack
587 switch (m_spellInfo->DmgClass)
588 {
592 else
594 break;
597 break;
598 default:
599 // Wands
602 else
604 break;
605 }
606
607 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
608
610 // wand case
613 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
614
615 if (originalCasterGUID)
616 m_originalCasterGUID = originalCasterGUID;
617 else
619
622 else
623 {
626 m_originalCaster = nullptr;
627 }
628
630 _triggeredCastFlags = triggerFlags;
631 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
633
634 m_CastItem = nullptr;
635
636 unitTarget = nullptr;
637 itemTarget = nullptr;
638 gameObjTarget = nullptr;
639 destTarget = nullptr;
640 damage = 0;
644 m_damage = 0;
645 m_healing = 0;
646 m_procAttacker = 0;
647 m_procVictim = 0;
648 m_procEx = 0;
649 focusObject = nullptr;
650 m_cast_count = 0;
651 m_glyphIndex = 0;
652 m_preCastSpell = 0;
653 m_spellAura = nullptr;
654 _scriptsLoaded = false;
655
656 //Auto Shot & Shoot (wand)
658
659 m_runesState = 0;
660 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
661 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
662 m_timer = 0; // will set to castime in prepare
663 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
664 m_immediateHandled = false;
665
667
669
670 // Determine if spell can be reflected back to the caster
671 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
675
677 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
678
679 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
681
682 // xinef:
683 _spellTargetsSelected = false;
684
685 m_weaponItem = nullptr;
686}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
TriggerCastFlags
Definition: SpellDefines.h:129
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:138
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:136
#define sSpellMgr
Definition: SpellMgr.h:825
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1636
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:199
Definition: Item.h:220
bool IsPlayer() const
Definition: Object.h:197
Player * ToPlayer()
Definition: Object.h:198
bool IsInWorld() const
Definition: Object.h:104
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:490
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1255
uint32 getClassMask() const
Definition: Unit.h:749
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:653
bool m_referencedFromCurrentSpell
Definition: Spell.h:644
bool m_canReflect
Definition: Spell.h:620
uint32 m_procVictim
Definition: Spell.h:675
Unit * m_originalCaster
Definition: Spell.h:608
bool m_needComboPoints
Definition: Spell.h:646
uint64 m_delayStart
Definition: Spell.h:638
bool _scriptsLoaded
Definition: Spell.h:726
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:767
int32 damage
Definition: Spell.h:655
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:656
int32 m_channeledDuration
Definition: Spell.h:619
Aura * m_spellAura
Definition: Spell.h:658
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:701
Unit *const m_caster
Definition: Spell.h:602
uint8 m_delayAtDamageCount
Definition: Spell.h:627
WeaponAttackType m_attackType
Definition: Spell.h:616
bool m_immediateHandled
Definition: Spell.h:641
uint32 m_spellState
Definition: Spell.h:763
ObjectGuid m_originalCasterGUID
Definition: Spell.h:606
void CleanupTargetList()
Definition: Spell.cpp:2370
int32 m_timer
Definition: Spell.h:764
int32 m_casttime
Definition: Spell.h:618
Item * itemTarget
Definition: Spell.h:652
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:668
bool m_executedCurrently
Definition: Spell.h:645
DiminishingLevels m_diminishLevel
Definition: Spell.h:661
float m_damageMultipliers[3]
Definition: Spell.h:648
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:781
uint8 m_auraScaleMask
Definition: Spell.h:775
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:622
bool m_skipCheck
Definition: Spell.h:774
int32 m_healing
Definition: Spell.h:669
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:683
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:651
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:615
SpellEvent * _spellEvent
Definition: Spell.h:766
bool _spellTargetsSelected
Definition: Spell.h:779
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:654
Spell ** m_selfContainer
Definition: Spell.h:610
uint8 m_applyMultiplierMask
Definition: Spell.h:647
DiminishingGroup m_diminishGroup
Definition: Spell.h:662
uint32 m_procEx
Definition: Spell.h:676
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:604
int32 m_powerCost
Definition: Spell.h:617
uint32 m_procAttacker
Definition: Spell.h:674
GameObject * focusObject
Definition: Spell.h:665
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:625
bool m_autoRepeat
Definition: Spell.h:624
bool IsPassive() const
Definition: SpellInfo.cpp:1097
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1265
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:875
bool IsPositive() const
Definition: SpellInfo.cpp:1236
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1282
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1275
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
689{
690 // unload scripts
691 while (!m_loadedScripts.empty())
692 {
693 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
694 (*itr)->_Unload();
695 delete (*itr);
696 m_loadedScripts.erase(itr);
697 }
698
700 {
701 // Clean the reference to avoid later crash.
702 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
703 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
704 *m_selfContainer = nullptr;
705 }
706
707 delete m_spellValue;
708
710}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
void CheckEffectExecuteData()
Definition: Spell.cpp:8488
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:741
uint32 Id
Definition: SpellInfo.h:320

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3807{
3808 // update pointers base at GUIDs to prevent access to non-existed already object
3809 if (!UpdatePointers())
3810 {
3811 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3812 cancel();
3813 return;
3814 }
3815
3816 // cancel at lost explicit target during cast
3818 {
3819 cancel();
3820 return;
3821 }
3822
3823 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3825 {
3827 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3829
3830 if (Unit* charm = m_caster->GetCharm())
3831 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3832 }
3833
3834 if (Player* playerCaster = m_caster->ToPlayer())
3835 {
3836 // now that we've done the basic check, now run the scripts
3837 // should be done before the spell is actually executed
3838 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3839
3840 // As of 3.0.2 pets begin attacking their owner's target immediately
3841 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3842 // This prevents spells such as Hunter's Mark from triggering pet attack
3843 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3845 if (!playerCaster->m_Controlled.empty())
3846 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3847 if (Unit* pet = *itr)
3848 if (pet->IsAlive() && pet->IsCreature())
3849 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3850 }
3851
3853
3857
3859
3860 Player* modOwner = m_caster->GetSpellModOwner();
3861 // skip check if done already (for instant cast spells for example)
3862 if (!skipCheck)
3863 {
3864 SpellCastResult castResult = CheckCast(false);
3865 if (castResult != SPELL_CAST_OK)
3866 {
3867 SendCastResult(castResult);
3868 SendInterrupted(0);
3869
3870 finish(false);
3871 SetExecutedCurrently(false);
3872 return;
3873 }
3874
3875 // additional check after cast bar completes (must not be in CheckCast)
3876 // if trade not complete then remember it in trade data
3878 {
3879 if (m_caster->IsPlayer())
3880 {
3881 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3882 {
3883 if (!my_trade->IsInAcceptProcess())
3884 {
3885 // Spell will be casted at completing the trade. Silently ignore at this place
3886 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3888 SendInterrupted(0);
3889
3890 finish(false);
3891 SetExecutedCurrently(false);
3892 return;
3893 }
3894 }
3895 }
3896 }
3897 }
3898
3899 if (modOwner)
3900 modOwner->SetSpellModTakingSpell(this, true);
3901
3904
3905 if (modOwner)
3906 modOwner->SetSpellModTakingSpell(this, false);
3907
3908 // Spell may be finished after target map check
3910 {
3911 SendInterrupted(0);
3912 finish(false);
3913 SetExecutedCurrently(false);
3914 return;
3915 }
3916
3917 if (modOwner)
3918 modOwner->SetSpellModTakingSpell(this, true);
3919
3921
3923
3924 if (modOwner)
3925 modOwner->SetSpellModTakingSpell(this, false);
3926
3927 // traded items have trade slot instead of guid in m_itemTargetGUID
3928 // set to real guid to be sent later to the client
3930
3931 if (m_caster->IsPlayer())
3932 {
3934 {
3937 }
3938
3940 }
3941
3943 {
3944 // Powers have to be taken before SendSpellGo
3945 TakePower();
3946 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3947 }
3948 else if (Item* targetItem = m_targets.GetItemTarget())
3949 {
3951 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3952 TakeReagents();
3953 }
3954
3956
3957 // CAST SPELL
3958 if (modOwner)
3959 modOwner->SetSpellModTakingSpell(this, true);
3960
3962
3964
3965 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3966 SendSpellGo();
3967
3968 if (modOwner)
3969 modOwner->SetSpellModTakingSpell(this, false);
3970
3971 if (m_originalCaster)
3972 {
3973 // Handle procs on cast
3974 uint32 procAttacker = m_procAttacker;
3975 if (!procAttacker)
3976 {
3977 bool IsPositive = m_spellInfo->IsPositive();
3979 {
3981 }
3982 else
3983 {
3985 }
3986 }
3987
3988 uint32 procEx = PROC_EX_NORMAL_HIT;
3989
3990 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3991 {
3992 if (ihit->missCondition != SPELL_MISS_NONE)
3993 {
3994 continue;
3995 }
3996
3997 if (!ihit->crit)
3998 {
3999 continue;
4000 }
4001
4002 procEx |= PROC_EX_CRITICAL_HIT;
4003 break;
4004 }
4005
4008 }
4009
4010 if (modOwner)
4011 modOwner->SetSpellModTakingSpell(this, true);
4012
4014 if (resetAttackTimers)
4015 {
4017 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4018 {
4019 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4020 {
4021 resetAttackTimers = false;
4022 break;
4023 }
4024 }
4025 }
4026
4027 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4028 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4029 {
4030 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4031 // in case delayed spell remove item at cast delay start
4032 TakeCastItem();
4033
4034 // Okay, maps created, now prepare flags
4035 m_immediateHandled = false;
4037 SetDelayStart(0);
4038
4041
4042 // remove all applied mods at this point
4043 // dont allow user to use them twice in case spell did not reach current target
4044 if (modOwner)
4045 modOwner->RemoveSpellMods(this);
4046
4047 // Xinef: why do we keep focus after spell is sent to air?
4048 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4049 // Xinef: we get focused to it out of nowhere...
4050 if (Creature* creatureCaster = m_caster->ToCreature())
4051 creatureCaster->ReleaseFocus(this);
4052 }
4053 else
4054 {
4055 // Immediate spell, no big deal
4057 }
4058
4059 if (resetAttackTimers)
4060 {
4061 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4062 {
4063 resetAttackTimers = false;
4064 }
4065
4066 if (resetAttackTimers)
4067 {
4069
4071 {
4073 }
4074
4076 }
4077 }
4078
4080
4081 if (modOwner)
4082 modOwner->SetSpellModTakingSpell(this, false);
4083
4084 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4085 {
4086 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4087 if (*i < 0)
4089 else
4091 }
4092
4093 // Interrupt Spell casting
4094 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4096 if (Unit* target = m_targets.GetUnitTarget())
4097 if (target->IsCreature())
4098 m_caster->CastSpell(target, 32747, true);
4099
4100 // xinef: start combat at cast for delayed spells, only for explicit target
4101 if (Unit* target = m_targets.GetUnitTarget())
4104 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4105
4106 if (m_caster->IsPlayer())
4109
4110 SetExecutedCurrently(false);
4111}
#define sScriptMgr
Definition: ScriptMgr.h:708
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
@ CHEAT_COOLDOWN
Definition: Player.h:1001
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:140
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:112
bool IsCreature() const
Definition: Object.h:201
Creature * ToCreature()
Definition: Object.h:202
Definition: Pet.h:41
Definition: Player.h:1064
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2127
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10077
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13923
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:10009
Pet * GetPet() const
Definition: Player.cpp:8906
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1178
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9057
TradeData * GetTradeData() const
Definition: Player.h:1370
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3503
Definition: TradeData.h:36
Definition: Unit.h:630
bool HasOffhandWeaponForAttack() const
Definition: Unit.h:1064
void ClearUnitState(uint32 f)
Definition: Unit.h:674
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1374
Unit * GetCharm() const
Definition: Unit.cpp:10635
Player * GetSpellModOwner() const
Definition: Unit.cpp:16542
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13669
bool IsPet() const
Definition: Unit.h:710
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4080
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1167
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4890
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6356
bool HasUnitState(const uint32 f) const
Definition: Unit.h:673
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10210
bool IsControlledByPlayer() const
Definition: Unit.h:1236
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20496
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:642
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:310
void UpdateTradeSlotItem()
Definition: Spell.cpp:347
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:315
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:231
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:575
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8542
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8748
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:553
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:772
void handle_immediate()
Definition: Spell.cpp:4113
void SendSpellGo()
Definition: Spell.cpp:4795
void TakeReagents()
Definition: Spell.cpp:5529
void SetExecutedCurrently(bool yes)
Definition: Spell.h:561
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5172
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8574
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8529
void cancel(bool bySelf=false)
Definition: Spell.cpp:3718
void SendSpellCooldown()
Definition: Spell.cpp:4353
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8516
void HandleLaunchPhase()
Definition: Spell.cpp:8229
bool UpdatePointers()
Definition: Spell.cpp:7859
void SetDelayStart(uint64 m_time)
Definition: Spell.h:563
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:682
void SelectSpellTargets()
Definition: Spell.cpp:814
void TakePower()
Definition: Spell.cpp:5313
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5651
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4667
uint64 GetDelayMoment() const
Definition: Spell.h:564
void TakeCastItem()
Definition: Spell.cpp:5250
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8073
void finish(bool ok=true)
Definition: Spell.cpp:4480
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1255
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2351
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:892

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4279{
4280 // Take for real after all targets are processed
4282 {
4284 }
4285
4286 // Real add combo points from effects
4288 {
4289 // remove Premed-like effects unless they were caused by ourselves
4290 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4292 {
4294 }
4295
4297 }
4298
4300 {
4302 }
4303
4306 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4307 {
4308 // Xinef: Properly clear infinite cooldowns in some cases
4309 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4312 }
4313
4314 // Handle procs on finish
4315 if (m_originalCaster)
4316 {
4317 uint32 procAttacker = m_procAttacker;
4318 if (!procAttacker)
4319 {
4320 bool IsPositive = m_spellInfo->IsPositive();
4322 {
4324 }
4325 else
4326 {
4328 }
4329 }
4330
4331 uint32 procEx = PROC_EX_NORMAL_HIT;
4332 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4333 {
4334 if (ihit->missCondition != SPELL_MISS_NONE)
4335 {
4336 continue;
4337 }
4338
4339 if (!ihit->crit)
4340 {
4341 continue;
4342 }
4343
4344 procEx |= PROC_EX_CRITICAL_HIT;
4345 break;
4346 }
4347
4350 }
4351}
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:797
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11105
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:1017
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10585
void ClearComboPoints()
Definition: Unit.cpp:16829
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16803
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5088
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8063
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1211

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4251{
4252 m_spellAura = nullptr;
4253 // initialize Diminishing Returns Data
4256
4257 // handle some immediate features of the spell here
4259
4261
4262 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4263 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4264 {
4265 // don't do anything for empty effect
4266 if (!m_spellInfo->Effects[j].IsEffect())
4267 continue;
4268
4269 // call effect handlers to handle destination hit
4270 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4271 }
4272
4273 // process items
4274 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4275 DoAllEffectOnTarget(&(*ihit));
4276}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5578
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5625
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:699
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2608
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
531 {
532 if (target != m_comboTarget)
533 {
534 m_comboTarget = target;
535 m_comboPointGain = amount;
536 }
537 else
538 {
539 m_comboPointGain += amount;
540 }
541 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2604{
2605 m_destTargets[effIndex] = dest;
2606}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2513{
2514 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2515 {
2516 if (!m_spellInfo->Effects[effIndex].IsEffect())
2517 effectMask &= ~(1 << effIndex);
2518 else
2519 {
2520 switch (m_spellInfo->Effects[effIndex].Effect)
2521 {
2525 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2526 effectMask &= ~(1 << effIndex);
2527 break;
2528 default:
2529 break;
2530 }
2531 }
2532 }
2533
2534 if (!effectMask)
2535 return;
2536
2537 ObjectGuid targetGUID = go->GetGUID();
2538
2539 // Lookup target in already in list
2540 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2541 {
2542 if (targetGUID == ihit->targetGUID) // Found in list
2543 {
2544 ihit->effectMask |= effectMask; // Add only effect mask
2545 return;
2546 }
2547 }
2548
2549 // This is new target calculate data for him
2550
2551 GOTargetInfo target;
2552 target.targetGUID = targetGUID;
2553 target.effectMask = effectMask;
2554 target.processed = false; // Effects not apply on target
2555
2556 // Spell have speed - need calculate incoming time
2557 if (m_spellInfo->Speed > 0.0f)
2558 {
2559 // calculate spell incoming interval
2560 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2561 if (dist < 5.0f)
2562 dist = 5.0f;
2563 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2564 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2565 m_delayMoment = target.timeDelay;
2566 }
2567 else
2568 target.timeDelay = 0LL;
2569
2570 // Add target to list
2571 m_UniqueGOTargetInfo.push_back(target);
2572}
std::uint64_t uint64
Definition: Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1593
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:866
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:867
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:865
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245
Definition: ObjectGuid.h:118
uint64 m_delayMoment
Definition: Spell.h:639
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:692

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2575{
2576 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2577 if (!m_spellInfo->Effects[effIndex].IsEffect())
2578 effectMask &= ~(1 << effIndex);
2579
2580 // no effects left
2581 if (!effectMask)
2582 return;
2583
2584 // Lookup target in already in list
2585 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2586 {
2587 if (item == ihit->item) // Found in list
2588 {
2589 ihit->effectMask |= effectMask; // Add only effect mask
2590 return;
2591 }
2592 }
2593
2594 // This is new target add data
2595
2596 ItemTargetInfo target;
2597 target.item = item;
2598 target.effectMask = effectMask;
2599
2600 m_UniqueItemInfo.push_back(target);
2601}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2380{
2381 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2382 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2383 effectMask &= ~(1 << effIndex);
2384
2385 // no effects left
2386 if (!effectMask)
2387 return;
2388
2389 if (checkIfValid)
2390 {
2391 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2392 if (res != SPELL_CAST_OK)
2393 return;
2394 }
2395
2396 // Check for effect immune skip if immuned
2397 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2398 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2399 effectMask &= ~(1 << effIndex);
2400
2401 ObjectGuid targetGUID = target->GetGUID();
2402
2403 // Lookup target in already in list
2404 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2405 {
2406 if (targetGUID == ihit->targetGUID) // Found in list
2407 {
2408 ihit->effectMask |= effectMask; // Immune effects removed from mask
2409 ihit->scaleAura = false;
2410 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2411 {
2412 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2413 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2414 ihit->scaleAura = true;
2415 }
2416
2417 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2418 return;
2419 }
2420 }
2421
2422 // This is new target calculate data for him
2423
2424 // Get spell hit result on target
2425 TargetInfo targetInfo;
2426 targetInfo.targetGUID = targetGUID; // Store target GUID
2427 targetInfo.effectMask = effectMask; // Store all effects not immune
2428 targetInfo.processed = false; // Effects not apply on target
2429 targetInfo.alive = target->IsAlive();
2430 targetInfo.damage = 0;
2431 targetInfo.crit = false;
2432 targetInfo.scaleAura = false;
2433 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2434 {
2435 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2436 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2437 targetInfo.scaleAura = true;
2438 }
2439
2440 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2441
2442 // Calculate hit result
2443 if (m_originalCaster)
2444 {
2445 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2446 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2447 {
2448 targetInfo.missCondition = SPELL_MISS_NONE;
2449 }
2450 }
2451 else
2452 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2453
2454 // Spell have speed - need calculate incoming time
2455 // Incoming time is zero for self casts. At least I think so.
2456 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2457 {
2458 // calculate spell incoming interval
2460 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2461
2462 if (dist < 5.0f)
2463 dist = 5.0f;
2464 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2465
2466 // Calculate minimum incoming time
2467 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2468 m_delayMoment = targetInfo.timeDelay;
2469 }
2470 else
2471 targetInfo.timeDelay = 0LL;
2472
2473 // If target reflect spell back to caster
2474 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2475 {
2476 // Calculate reflected spell result on caster
2478
2479 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2480 targetInfo.reflectResult = SPELL_MISS_PARRY;
2481
2482 // Increase time interval for reflected spells by 1.5
2484 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2485
2487
2488 // HACK: workaround check for succubus seduction case
2490 if (m_caster->IsPet())
2491 {
2492 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2493 switch (ci->family)
2494 {
2496 {
2497 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2498 cancel();
2499 }
2500 break;
2501 return;
2502 }
2503 }
2504 }
2505 else
2506 targetInfo.reflectResult = SPELL_MISS_NONE;
2507
2508 // Add target to list
2509 m_UniqueTargetInfo.push_back(targetInfo);
2510}
#define sObjectMgr
Definition: ObjectMgr.h:1621
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:82
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2664
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1523
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1526
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1525
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1530
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
Definition: CreatureData.h:187
uint32 family
Definition: CreatureData.h:218
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
bool IsAlive() const
Definition: Unit.h:1216
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3453
EventProcessor m_Events
Definition: Unit.h:1809
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:12970
uint8 GetLevel() const
Definition: Unit.h:855
Definition: Spell.h:254
bool processed
Definition: Spell.h:260
int32 damage
Definition: Spell.h:264
SpellMissInfo missCondition
Definition: Spell.h:257
bool scaleAura
Definition: Spell.h:263
bool crit
Definition: Spell.h:262
uint64 timeDelay
Definition: Spell.h:256
ObjectGuid targetGUID
Definition: Spell.h:255
SpellMissInfo reflectResult
Definition: Spell.h:258
bool alive
Definition: Spell.h:261
uint8 effectMask
Definition: Spell.h:259
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7921
Definition: Spell.h:846
Definition: SpellInfo.h:316
uint32 SpellLevel
Definition: SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2500
uint32 SpellIconID
Definition: SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1758

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
895{
896 if (m_targets.HasDst())
897 {
898 if (m_targets.HasTraj())
899 {
900 float speed = m_targets.GetSpeedXY();
901 if (speed > 0.0f)
902 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
903 }
904 else if (m_spellInfo->Speed > 0.0f)
905 {
906 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
907 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
908 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
909 }
910 }
911
912 return 0;
913}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
bool HasTraj() const
Definition: Spell.h:166
bool HasDst() const
Definition: Spell.h:165
float GetSpeedXY() const
Definition: Spell.h:174
float GetDist2d() const
Definition: Spell.h:173
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:400

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1155{
1156 if (m_spellInfo->Effects[i].MiscValue)
1157 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1158 else if (m_spellInfo->Effects[i].MiscValueB)
1159 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1160 else
1161 speedZ = 10.0f;
1162 speedXY = dist * 10.0f / speedZ;
1163}

References SpellInfo::Effects, and m_spellInfo.

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14815
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:213

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8543{
8544 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8545 {
8546 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8547 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8548 for (; hookItr != hookItrEnd; ++hookItr)
8549 (*hookItr).Call(*scritr);
8550
8551 (*scritr)->_FinishScriptCall();
8552 }
8553}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8655{
8656 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8657 {
8658 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8659 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8660 for (; hookItr != hookItrEnd; ++hookItr)
8661 (*hookItr).Call(*scritr);
8662
8663 (*scritr)->_FinishScriptCall();
8664 }
8665}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8517{
8518 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8519 {
8520 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8521 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8522 for (; hookItr != hookItrEnd; ++hookItr)
8523 (*hookItr).Call(*scritr);
8524
8525 (*scritr)->_FinishScriptCall();
8526 }
8527}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8629{
8630 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8631 {
8632 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8633 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8634 for (; hookItr != hookItrEnd; ++hookItr)
8635 (*hookItr).Call(*scritr, missInfo);
8636
8637 (*scritr)->_FinishScriptCall();
8638 }
8639}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8556{
8558 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8559 {
8560 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8561 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8562 for (; hookItr != hookItrEnd; ++hookItr)
8563 {
8564 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8565 if (retVal == SPELL_CAST_OK)
8566 retVal = tempResult;
8567 }
8568
8569 (*scritr)->_FinishScriptCall();
8570 }
8571 return retVal;
8572}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8696{
8697 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8698 {
8699 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8700 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8701 for (; hookItr != hookItrEnd; ++hookItr)
8702 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8703 hookItr->Call(*scritr, target);
8704
8705 (*scritr)->_FinishScriptCall();
8706 }
8707}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8581{
8582 // execute script effect handler hooks and check if effects was prevented
8583 bool preventDefault = false;
8584 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8585 {
8586 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8587 SpellScriptHookType hookType;
8588 switch (mode)
8589 {
8591 effItr = (*scritr)->OnEffectLaunch.begin();
8592 effEndItr = (*scritr)->OnEffectLaunch.end();
8594 break;
8596 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8597 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8599 break;
8601 effItr = (*scritr)->OnEffectHit.begin();
8602 effEndItr = (*scritr)->OnEffectHit.end();
8604 break;
8606 effItr = (*scritr)->OnEffectHitTarget.begin();
8607 effEndItr = (*scritr)->OnEffectHitTarget.end();
8609 break;
8610 default:
8611 ABORT();
8612 return false;
8613 }
8614 (*scritr)->_PrepareScriptCall(hookType);
8615 for (; effItr != effEndItr; ++effItr)
8616 // effect execution can be prevented
8617 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8618 (*effItr).Call(*scritr, effIndex);
8619
8620 if (!preventDefault)
8621 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8622
8623 (*scritr)->_FinishScriptCall();
8624 }
8625 return preventDefault;
8626}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:234
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:236
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8668{
8669 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8670 {
8671 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8672 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8673 for (; hookItr != hookItrEnd; ++hookItr)
8674 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8675 hookItr->Call(*scritr, targets);
8676
8677 (*scritr)->_FinishScriptCall();
8678 }
8679}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8682{
8683 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8684 {
8685 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8686 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8687 for (; hookItr != hookItrEnd; ++hookItr)
8688 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8689 hookItr->Call(*scritr, target);
8690
8691 (*scritr)->_FinishScriptCall();
8692 }
8693}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8530{
8531 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8532 {
8533 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8534 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8535 for (; hookItr != hookItrEnd; ++hookItr)
8536 (*hookItr).Call(*scritr);
8537
8538 (*scritr)->_FinishScriptCall();
8539 }
8540}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8642{
8643 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8644 {
8645 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8646 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8647 for (; hookItr != hookItrEnd; ++hookItr)
8648 (*hookItr).Call(*scritr);
8649
8650 (*scritr)->_FinishScriptCall();
8651 }
8652}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7006{
7007 ObjectGuid targetguid = target->GetGUID();
7008
7009 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7010 {
7012 {
7013 if (m_spellInfo->StackAmount <= 1)
7014 {
7015 if (target->HasAuraEffect(m_spellInfo->Id, j))
7016 return false;
7017 }
7018 else
7019 {
7020 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7021 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7022 return false;
7023 }
7024 }
7025 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7026 {
7027 if (target->HasAuraEffect(m_spellInfo->Id, j))
7028 return false;
7029 }
7030 }
7031
7032 SpellCastResult result = CheckPetCast(target);
7033
7034 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7035 {
7037 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7038 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7039 if (ihit->targetGUID == targetguid)
7040 return true;
7041 }
7042 return false; //target invalid
7043}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5472
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5646
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6812
uint32 StackAmount
Definition: SpellInfo.h:371

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3719{
3721 return;
3722
3723 uint32 oldState = m_spellState;
3725
3726 m_autoRepeat = false;
3727 switch (oldState)
3728 {
3732
3733 if (m_caster->IsPlayer())
3734 {
3736 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3737 }
3738 [[fallthrough]];
3741 break;
3743 if (!bySelf)
3744 {
3745 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3746 if ((*ihit).missCondition == SPELL_MISS_NONE)
3747 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3748 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3749
3752
3755 }
3756
3758 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3759
3760 // spell is canceled-take mods and clear list
3761 if (Player* player = m_caster->GetSpellModOwner())
3762 player->RemoveSpellMods(this);
3763
3764 m_appliedMods.clear();
3765 break;
3766 default:
3767 break;
3768 }
3769
3771 if (m_selfContainer && *m_selfContainer == this)
3772 *m_selfContainer = nullptr;
3773
3774 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3776 {
3778 }
3779
3780 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3782
3783 //set state back so finish will be processed
3784 m_spellState = oldState;
3785
3786 finish(false);
3787}
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:850
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:532
bool NeedSendSpectatorData() const
Definition: Player.cpp:15405
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6175
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6119
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5189
void CancelGlobalCooldown()
Definition: Spell.cpp:8883
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:559
UsedSpellMods m_appliedMods
Definition: Spell.h:545

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8884{
8886 return;
8887
8888 // Cancel global cooldown when interrupting current cast
8890 return;
8891
8892 // Only players or controlled units have global cooldown
8893 if (m_caster->GetCharmInfo())
8895 else if (m_caster->IsPlayer())
8897}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1787
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:416
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:158
CharmInfo * GetCharmInfo()
Definition: Unit.h:1290
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1468
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8733{
8734 // Relentless strikes, proc only from first effect
8735 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8736 return effMask & (1 << EFFECT_0);
8737
8738 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8739 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8740 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8741 {
8742 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8743 return true;
8744 }
8745 return effMask;
8746}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8357{
8358 if (!lockId) // possible case for GO and maybe for items.
8359 return SPELL_CAST_OK;
8360
8361 // Get LockInfo
8362 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8363
8364 if (!lockInfo)
8366
8367 bool reqKey = false; // some locks not have reqs
8368
8369 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8370 {
8371 switch (lockInfo->Type[j])
8372 {
8373 // check key item (many fit cases can be)
8374 case LOCK_KEY_ITEM:
8375 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8376 return SPELL_CAST_OK;
8377 reqKey = true;
8378 break;
8379 // check key skill (only single first fit case can be)
8380 case LOCK_KEY_SKILL:
8381 {
8382 reqKey = true;
8383
8384 // wrong locktype, skip
8385 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8386 continue;
8387
8388 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8389
8390 if (skillId != SKILL_NONE)
8391 {
8392 reqSkillValue = lockInfo->Skill[j];
8393
8394 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8395 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8396 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8397
8398 // skill bonus provided by casting spell (mostly item spells)
8399 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8400 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8402 {
8403 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8404 }
8405
8406 if (skillValue < reqSkillValue)
8408 }
8409
8410 return SPELL_CAST_OK;
8411 }
8412 case LOCK_KEY_SPELL:
8413 {
8414 if (m_spellInfo->Id == lockInfo->Index[j])
8415 {
8416 return SPELL_CAST_OK;
8417 }
8418 reqKey = true;
8419 break;
8420 }
8421 }
8422 }
8423
8424 if (reqKey)
8426
8427 return SPELL_CAST_OK;
8428}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1430
LockType
Definition: SharedDefines.h:2591
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2585
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2586
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2587
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:961
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:998
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:3020
@ SKILL_NONE
Definition: SharedDefines.h:2864
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2975
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1304
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5437
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1004
Definition: DBCStructure.h:1307
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1309
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1311

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3790{
3791 Player* modOwner = m_caster->GetSpellModOwner();
3792 Spell* lastMod = nullptr;
3793 if (modOwner)
3794 {
3795 lastMod = modOwner->m_spellModTakingSpell;
3796 if (lastMod)
3797 modOwner->SetSpellModTakingSpell(lastMod, false);
3798 }
3799
3800 _cast(skipCheck);
3801
3802 if (lastMod)
3803 modOwner->SetSpellModTakingSpell(lastMod, true);
3804}
Spell * m_spellModTakingSpell
Definition: Player.h:2534
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3806

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5652{
5653 // check death state
5656
5657 // Spectator check
5658 if (m_caster->IsPlayer())
5659 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5660 return SPELL_FAILED_NOT_HERE;
5661
5663
5664 sScriptMgr->OnSpellCheckCast(this, strict, res);
5665
5666 if (res != SPELL_CAST_OK)
5667 return res;
5668
5669 // check cooldowns to prevent cheating
5671 {
5672 if (m_caster->IsPlayer())
5673 {
5674 //can cast triggered (by aura only?) spells while have this flag
5677
5679 {
5682 else
5684 }
5685
5686 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5689 }
5692 }
5693
5695 {
5698 }
5699
5700 // Check global cooldown
5703
5704 // only triggered spells can be processed an ended battleground
5705 if (!IsTriggered() && m_caster->IsPlayer())
5707 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5709
5710 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5711 {
5713 !m_caster->IsOutdoors())
5715
5719 }
5720
5721 // only check at first call, Stealth auras are already removed at second call
5722 // for now, ignore triggered spells
5724 {
5725 bool checkForm = true;
5726 // Ignore form req aura
5728 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5729 {
5730 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5731 continue;
5732 checkForm = false;
5733 break;
5734 }
5735 if (checkForm)
5736 {
5737 // Cannot be used in this stance/form
5739 if (shapeError != SPELL_CAST_OK)
5740 return shapeError;
5741
5744 }
5745 }
5746
5748 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5749 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5751
5752 bool reqCombat = true;
5754 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5755 {
5756 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5757 {
5758 m_needComboPoints = false;
5759 if ((*j)->GetMiscValue() == 1)
5760 {
5761 reqCombat = false;
5762 break;
5763 }
5764 }
5765 }
5766
5767 // caster state requirements
5768 // not for triggered spells (needed by execute)
5770 {
5775
5776 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5781
5782 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5784 }
5785
5786 // Xinef: exploit protection
5788 {
5789 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5790 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5791 if (instanceScript->IsEncounterInProgress())
5792 {
5793 if (Group* group = m_caster->ToPlayer()->GetGroup())
5794 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5795 if (Player* member = itr->GetSource())
5796 if (member->IsInMap(m_caster))
5797 if (Unit* victim = member->GetVictim())
5798 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5799 {
5800 m_caster->CombatStart(victim);
5801 victim->AddThreat(m_caster, 1.0f);
5802 break;
5803 }
5805 }
5806 }
5807
5808 // cancel autorepeat spells if cast start when moving
5809 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5810 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5811 {
5812 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5815 return SPELL_FAILED_MOVING;
5816 }
5817
5818 Vehicle* vehicle = m_caster->GetVehicle();
5820 {
5821 uint16 checkMask = 0;
5822 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5823 {
5824 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5826 {
5827 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5828 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5829 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5830 break;
5831 }
5832 }
5833
5836
5837 if (!checkMask)
5838 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5839
5840 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5841 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5843 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5845 }
5846
5847 // check spell cast conditions from database
5848 {
5851 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5852 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5853 {
5854 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5855 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5856 {
5860 }
5861 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5864 }
5865 }
5866
5867 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5868 // those spells may have incorrect target entries or not filled at all (for example 15332)
5869 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5870 // also, such casts shouldn't be sent to client
5871 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5873 {
5874 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5875 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5877 {
5879 if (castResult != SPELL_CAST_OK)
5880 return castResult;
5881 }
5882 }
5883
5884 if (Unit* target = m_targets.GetUnitTarget())
5885 {
5886 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5887 if (castResult != SPELL_CAST_OK)
5888 return castResult;
5889
5890 if (target != m_caster)
5891 {
5892 // Must be behind the target
5893 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5895
5896 // Target must be facing you
5897 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5899
5902 {
5903 bool castedByGameobject = false;
5904 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5906 {
5907 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5908 }
5909 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5910 {
5911 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5912 {
5913 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5914 }
5915 }
5916
5917 if (castedByGameobject)
5918 {
5919 // If spell casted by gameobject then ignore M2 models
5920 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5921 }
5922
5924 {
5926 }
5927 }
5928 }
5929 }
5930
5931 // Check for line of sight for spells with dest
5932 if (m_targets.HasDst())
5933 {
5934 float x, y, z;
5935 m_targets.GetDstPos()->GetPosition(x, y, z);
5936
5939 {
5940 bool castedByGameobject = false;
5941 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5943 {
5944 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5945 }
5946 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5947 {
5948 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5949 {
5950 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5951 }
5952 }
5953
5954 if (castedByGameobject)
5955 {
5956 // If spell casted by gameobject then ignore M2 models
5957 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5958 }
5959
5961 {
5963 }
5964 }
5965 }
5966
5967 // check pet presence
5968 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5969 {
5970 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5971 {
5973 {
5974 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5976 else
5977 return SPELL_FAILED_NO_PET;
5978 }
5979 break;
5980 }
5981 }
5982 // Spell casted only on battleground
5984 if (!m_caster->ToPlayer()->InBattleground())
5986
5987 // do not allow spells to be cast in arenas
5988 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5989 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5992 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5993 if (mapEntry->IsBattleArena())
5995
5996 // zone check
5998 {
5999 uint32 zone, area;
6000 m_caster->GetZoneAndAreaId(zone, area);
6001
6003 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
6004 if (locRes != SPELL_CAST_OK)
6005 return locRes;
6006 }
6007
6008 // not let players cast spells at mount (and let do it to creatures)
6011 {
6012 if (m_caster->IsInFlight())
6014 else
6016 }
6017
6018 SpellCastResult castResult = SPELL_CAST_OK;
6019
6020 // always (except passive spells) check items (focus object can be required for any type casts)
6021 if (!m_spellInfo->IsPassive())
6022 {
6023 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6024 castResult = CheckSpellFocus();
6025 if (castResult != SPELL_CAST_OK)
6026 return castResult;
6027
6028 castResult = CheckItems();
6029 if (castResult != SPELL_CAST_OK)
6030 return castResult;
6031 }
6032
6033 // Triggered spells also have range check
6035 castResult = CheckRange(strict);
6036 if (castResult != SPELL_CAST_OK)
6037 return castResult;
6038
6040 {
6041 castResult = CheckPower();
6042 if (castResult != SPELL_CAST_OK)
6043 return castResult;
6044 }
6045
6047 {
6048 return SPELL_CAST_OK;
6049 }
6050
6051 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6053 {
6055 if (castResult != SPELL_CAST_OK)
6056 return castResult;
6057
6058 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6060 {
6062 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6063 if (itr->type == m_spellInfo->Mechanic)
6065 }
6066 }
6067
6068 // script hook
6069 castResult = CallScriptCheckCastHandlers();
6070 if (castResult != SPELL_CAST_OK)
6071 return castResult;
6072
6073 bool hasDispellableAura = false;
6074 bool hasNonDispelEffect = false;
6075 uint32 dispelMask = 0;
6076 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6077 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6078 {
6080 {
6081 hasDispellableAura = true;
6082 break;
6083 }
6084
6085 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6086 }
6087 else if (m_spellInfo->Effects[i].IsEffect())
6088 {
6089 hasNonDispelEffect = true;
6090 break;
6091 }
6092
6093 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6094 {
6095 if (Unit* target = m_targets.GetUnitTarget())
6096 {
6097 // Xinef: do not allow to cast on hostile targets in sanctuary
6098 if (!m_caster->IsFriendlyTo(target))
6099 {
6100 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6101 {
6102 // Xinef: fix for duels
6103 Player* player = m_caster->ToPlayer();
6104 if (!player || !player->duel || target != player->duel->Opponent)
6106 }
6107 }
6108
6109 DispelChargesList dispelList;
6110 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6111
6112 if (dispelList.empty())
6114 }
6115 }
6116
6117 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6118 {
6119 // for effects of spells that have only one target
6120 switch (m_spellInfo->Effects[i].Effect)
6121 {
6123 {
6124 if (!m_caster->IsPlayer())
6126
6127 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6128 break;
6129
6130 Pet* pet = m_caster->ToPlayer()->GetPet();
6131
6132 if (!pet)
6133 return SPELL_FAILED_NO_PET;
6134
6135 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6136
6137 if (!learn_spellproto)
6139
6140 if (m_spellInfo->SpellLevel > pet->GetLevel())
6141 return SPELL_FAILED_LOWLEVEL;
6142
6143 break;
6144 }
6146 {
6147 // check target only for unit target case
6149 {
6150 if (!m_caster->IsPlayer())
6152
6153 Pet* pet = unitTarget->ToPet();
6154 if (!pet || pet->GetOwner() != m_caster)
6156
6157 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6158
6159 if (!learn_spellproto)
6161
6162 if (m_spellInfo->SpellLevel > pet->GetLevel())
6163 return SPELL_FAILED_LOWLEVEL;
6164 }
6165 break;
6166 }
6168 {
6169 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6170 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6171 if (m_caster->HasAura(gp->SpellId))
6173 break;
6174 }
6176 {
6177 if (!m_caster->IsPlayer())
6179
6180 Item* foodItem = m_targets.GetItemTarget();
6181 if (!foodItem)
6183
6184 Pet* pet = m_caster->ToPlayer()->GetPet();
6185
6186 if (!pet)
6187 return SPELL_FAILED_NO_PET;
6188
6189 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6191
6192 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6194
6195 if (m_caster->IsInCombat() || pet->IsInCombat())
6197
6198 break;
6199 }
6202 {
6203 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6204 if (m_caster->IsPlayer())
6205 if (Unit* target = m_targets.GetUnitTarget())
6206 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6208 break;
6209 }
6211 {
6213 {
6215 }
6216
6218 {
6219 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6220 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6222 }
6224 {
6225 // Exception for Master's Call
6226 if (m_spellInfo->Id != 54216)
6227 {
6228 return SPELL_FAILED_ROOTED;
6229 }
6230 }
6231 if (m_caster->IsPlayer())
6232 if (Unit* target = m_targets.GetUnitTarget())
6233 if (!target->IsAlive())
6235 // Xinef: Pass only explicit unit target spells
6236 // pussywizard:
6238 {
6239 Unit* target = m_targets.GetUnitTarget();
6240 if (!target)
6242
6243 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6244 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6246
6247 float objSize = target->GetCombatReach();
6248 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6249
6250 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6251 m_preGeneratedPath->SetPathLengthLimit(range);
6252
6253 // first try with raycast, if it fails fall back to normal path
6254 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6255 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6256 return SPELL_FAILED_NOPATH;
6257 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6258 return SPELL_FAILED_NOPATH;
6259 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6260 return SPELL_FAILED_NOPATH;
6261
6262 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6263 }
6264 if (Player* player = m_caster->ToPlayer())
6265 player->SetCanTeleport(true);
6266 break;
6267 }
6269 {
6272
6275
6276 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6277 if (!creature->IsCritter() && !creature->loot.isLooted())
6279
6280 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6281
6282 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6283 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6284 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6285 if (ReqValue > skillValue)
6287
6288 break;
6289 }
6291 {
6292 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6293 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6294 break;
6295
6296 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6297 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6298 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6300
6301 Item* pTempItem = nullptr;
6303 {
6304 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6305 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6306 }
6309
6310 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6311 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6313 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6315
6316 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6317 if (GameObject* go = m_targets.GetGOTarget())
6318 {
6319 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6320 {
6322 }
6323 }
6324 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6326 {
6327 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6328 {
6329 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6331 }
6332 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6335 }
6336
6337 // get the lock entry
6338 uint32 lockId = 0;
6339 if (GameObject* go = m_targets.GetGOTarget())
6340 {
6341 lockId = go->GetGOInfo()->GetLockId();
6342 if (!lockId)
6344 }
6345 else if (Item* itm = m_targets.GetItemTarget())
6346 lockId = itm->GetTemplate()->LockID;
6347
6348 SkillType skillId = SKILL_NONE;
6349 int32 reqSkillValue = 0;
6350 int32 skillValue = 0;
6351
6352 // check lock compatibility
6353 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6354 if (res != SPELL_CAST_OK)
6355 return res;
6356
6357 // chance for fail at lockpicking attempt
6358 // second check prevent fail at rechecks
6359 // herbalism and mining cannot fail as of patch 3.1.0
6360 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6361 {
6362 // chance for failure in orange lockpick
6363 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6364 {
6366 }
6367 }
6368 break;
6369 }
6371 {
6372 Unit* unitCaster = m_caster->ToUnit();
6373 if (!unitCaster)
6374 {
6376 }
6377
6378 Creature* pet = unitCaster->GetGuardianPet();
6379 if (pet)
6380 {
6381 if (pet->IsAlive())
6382 {
6384 }
6385 }
6386 else if (Player* playerCaster = m_caster->ToPlayer())
6387 {
6388 PetStable& petStable = playerCaster->GetOrInitPetStable();
6389 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6390 {
6391 return SPELL_FAILED_NO_PET;
6392 }
6393 }
6394
6395 break;
6396 }
6397 // This is generic summon effect
6399 {
6400 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6401 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6402 break;
6403 switch (SummonProperties->Category)
6404 {
6406 if (m_caster->GetPetGUID())
6408 [[fallthrough]];
6410 if (m_caster->GetCharmGUID())
6412 break;
6413 }
6414 break;
6415 }
6417 {
6419 {
6424 }
6425 break;
6426 }
6428 {
6429 Unit* unitCaster = m_caster->ToUnit();
6430 if (!unitCaster)
6432
6434 {
6435 if (m_caster->GetPetGUID())
6437 if (m_caster->GetCharmGUID())
6439 }
6440
6442 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6443 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6444
6445 Player* playerCaster = unitCaster->ToPlayer();
6446 if (playerCaster && playerCaster->GetPetStable())
6447 {
6448 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6449 if (info.first)
6450 {
6451 if (info.first->Type == HUNTER_PET)
6452 {
6453 if (!info.first->Health)
6454 {
6455 playerCaster->SendTameFailure(PET_TAME_DEAD);
6457 }
6458
6459 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6460 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6461 {
6462 // if problem in exotic pet
6463 if (creatureInfo && creatureInfo->IsTameable(true))
6465 else
6467
6469 }
6470 }
6471 }
6472 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6473 {
6476 }
6477 }
6478 break;
6479 }
6481 {
6482 if (!m_caster->IsPlayer())
6484 if (!m_caster->GetTarget())
6486
6488 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6490
6491 // Xinef: Implement summon pending error
6492 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6494
6495 // check if our map is dungeon
6496 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6497 if (map->IsDungeon())
6498 {
6499 uint32 mapId = m_caster->GetMap()->GetId();
6500 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6501 /*if (map->IsRaid())
6502 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6503 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6504 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6505
6506 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6507 if (!instance)
6509 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6511 }
6512 break;
6513 }
6514 // RETURN HERE
6516 {
6517 if (!m_caster->IsPlayer())
6519
6520 Player* playerCaster = m_caster->ToPlayer();
6521 //
6522 if (!(playerCaster->GetTarget()))
6524
6526
6527 if (!target ||
6528 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6530
6531 // Xinef: Implement summon pending error
6532 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6534
6535 break;
6536 }
6537 case SPELL_EFFECT_LEAP:
6539 {
6540 //Do not allow to cast it before BG starts.
6541 if (m_caster->IsPlayer())
6542 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6543 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6545 break;
6546 }
6548 {
6551
6552 bool found = false;
6554 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6555 {
6556 if (itr->second->GetBase()->IsPassive())
6557 continue;
6558
6559 if (!itr->second->IsPositive())
6560 continue;
6561
6562 found = true;
6563 break;
6564 }
6565
6566 if (!found)
6568
6569 break;
6570 }
6572 {
6574 {
6575 if (m_caster->IsPlayer())
6576 return SPELL_FAILED_ROOTED;
6577 else
6579 }
6580 break;
6581 }
6582 // xinef: do not allow to use leaps while rooted
6583 case SPELL_EFFECT_JUMP:
6585 {
6587 return SPELL_FAILED_ROOTED;
6588 break;
6589 }
6591 if (!sScriptMgr->CanSelectSpecTalent(this))
6593 // can't change during already started arena/battleground
6594 if (m_caster->IsPlayer())
6595 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6596 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6598 break;
6599 default:
6600 break;
6601 }
6602 }
6603
6604 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6605 {
6606 switch (m_spellInfo->Effects[i].ApplyAuraName)
6607 {
6608 case SPELL_AURA_DUMMY:
6609 break;
6611 {
6612 if (!m_caster->IsPlayer())
6613 return SPELL_FAILED_NO_PET;
6614
6615 Pet* pet = m_caster->ToPlayer()->GetPet();
6616 if (!pet)
6617 return SPELL_FAILED_NO_PET;
6618
6619 if (pet->GetCharmerGUID())
6620 return SPELL_FAILED_CHARMED;
6621 break;
6622 }
6626 {
6627 if (m_caster->GetCharmerGUID())
6628 return SPELL_FAILED_CHARMED;
6629
6630 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6632 {
6633 if (m_caster->GetPetGUID())
6635
6636 if (m_caster->GetCharmGUID())
6638 }
6639 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6640 {
6641 if (m_caster->GetCharmGUID())
6643 }
6644
6645 if (Unit* target = m_targets.GetUnitTarget())
6646 {
6647 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6649
6650 if (target->IsMounted())
6652
6653 if (target->GetCharmerGUID())
6654 return SPELL_FAILED_CHARMED;
6655
6656 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6658
6659 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6661
6662 int32 damage = CalculateSpellDamage(i, target);
6663 if (damage && int32(target->GetLevel()) > damage)
6665 }
6666
6667 break;
6668 }
6669 case SPELL_AURA_MOUNTED:
6670 {
6671 // Disallow casting flying mounts in water
6674
6675 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6676 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6677 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6678 if (it)
6679 allowMount = it->AllowMount;
6680 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6682
6685
6686 // xinef: dont allow to cast mounts in specific transforms
6687 if (m_caster->getTransForm())
6688 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6689 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6690 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6692
6693 break;
6694 }
6696 {
6697 if (!m_targets.GetUnitTarget())
6699
6700 // can be casted at non-friendly unit or own pet/charm
6703
6704 break;
6705 }
6706 case SPELL_AURA_FLY:
6708 {
6709 // Xinef: added water check
6710 if (m_caster->IsInWater())
6712
6713 // not allow cast fly spells if not have req. skills (all spells is self target)
6714 // allow always ghost flight spells
6716 {
6717 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6718 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6719 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6720 return SPELL_FAILED_NOT_HERE;
6721 }
6722 break;
6723 }
6725 {
6726 if (m_spellInfo->Effects[i].IsTargetingArea())
6727 break;
6728
6729 if (!m_caster->IsPlayer() || m_CastItem)
6730 break;
6731
6732 if (!m_targets.GetUnitTarget())
6734
6737
6738 break;
6739 }
6740 case SPELL_AURA_HOVER:
6741 {
6743 {
6745 }
6746 break;
6747 }
6749 {
6750 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6751 {
6753 }
6754 break;
6755 }
6756 default:
6757 break;
6758 }
6759 }
6760
6761 // check trade slot case (last, for allow catch any another cast problems)
6763 {
6764 if (m_CastItem)
6766
6767 if (!m_caster->IsPlayer())
6769
6770 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6771
6772 if (!my_trade)
6774
6776 if (slot != TRADE_SLOT_NONTRADED)
6778
6779 if (!IsTriggered())
6780 if (my_trade->GetSpell())
6782 }
6783
6784 // check if caster has at least 1 combo point on target for spells that require combo points
6786 {
6788 {
6790 {
6792 }
6793 }
6794 else
6795 {
6796 if (!m_caster->GetComboPoints())
6797 {
6799 }
6800 }
6801 }
6802
6803 // xinef: check relic cooldown
6807
6808 // all ok
6809 return SPELL_CAST_OK;
6810}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
constexpr auto MINUTE
Definition: Common.h:47
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
std::int32_t int32
Definition: Define.h:103
std::uint16_t uint16
Definition: Define.h:108
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:203
@ STATUS_IN_PROGRESS
Definition: Battleground.h:202
LineOfSightChecks
Definition: Map.h:191
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:198
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:497
@ GO_STATE_READY
Definition: GameObjectData.h:690
@ INVTYPE_RELIC
Definition: ItemTemplate.h:284
@ HUNTER_PET
Definition: PetDefines.h:32
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:141
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:131
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:150
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:144
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:179
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:245
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:204
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:340
Definition: Battleground.h:303
Definition: ConditionMgr.h:181
Condition * mLastFailedCondition
Definition: ConditionMgr.h:183
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:182
uint32 ErrorType
Definition: ConditionMgr.h:204
uint8 ConditionTarget
Definition: ConditionMgr.h:208
uint32 ErrorTextId
Definition: ConditionMgr.h:205
Loot loot
Definition: Creature.h:229
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:208
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2827
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:258
bool IsTameable(bool exotic) const
Definition: CreatureData.h:275
Definition: TemporarySummon.h:40
Definition: GameObject.h:121
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:137
uint32 type
Definition: GameObjectData.h:33
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool IsPotion() const
Definition: Item.h:337
uint32 ItemLevel
Definition: ItemTemplate.h:635
uint32 LockID
Definition: ItemTemplate.h:669
uint32 InventoryType
Definition: ItemTemplate.h:632
Unit * ToUnit()
Definition: Object.h:206
Map * GetMap() const
Definition: Object.h:531
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
bool IsOutdoors() const
Definition: Object.cpp:3171
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetVisibilityRange() const
Definition: Object.cpp:1645
uint32 GetAreaId() const
Definition: Object.cpp:3154
uint32 GetZoneId() const
Definition: Object.cpp:3146
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3162
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2493
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1439
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1457
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2480
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1868
bool CanTameExoticPets() const
Definition: Player.h:2171
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13221
bool InBattleground() const
Definition: Player.h:2234
PetStable * GetPetStable()
Definition: Player.h:1202
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12195
WorldSession * GetSession() const
Definition: Player.h:1980
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16337
uint32 GetLastPotionId()
Definition: Player.h:1794
Group * GetGroup()
Definition: Player.h:2450
bool IsGameMaster() const
Definition: Player.h:1158
time_t GetSummonExpireTimer() const
Definition: Player.h:1101
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6707
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1108
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1860
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:409
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:713
Vehicle * GetVehicle() const
Definition: Unit.h:1687
Unit * GetOwner() const
Definition: Unit.cpp:10569
Pet * ToPet()
Definition: Unit.h:1728
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1741
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1475
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1742
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21236
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13593
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:688
bool IsInSanctuary() const
Definition: Unit.h:964
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:748
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5787
float GetCombatReach() const override
Definition: Unit.h:770
UnitFlags GetUnitFlags() const
Definition: Unit.h:681
TempSummon * ToTempSummon()
Definition: Unit.h:1730
bool HasStealthAura() const
Definition: Unit.h:1115
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5676
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1108
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1811
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19976
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1627
virtual bool IsInWater() const
Definition: Unit.cpp:4320
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10516
bool isMoving() const
Definition: Unit.h:1710
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1230
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1504
bool IsMounted() const
Definition: Unit.h:990
Unit * GetVictim() const
Definition: Unit.h:789
bool IsCritter() const
Definition: Unit.h:1106
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1222
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:1643
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1228
uint32 getTransForm() const
Definition: Unit.h:1527
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:890
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5212
bool IsTotem() const
Definition: Unit.h:712
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10620
ObjectGuid GetTarget() const
Definition: Unit.h:1756
bool IsInCombat() const
Definition: Unit.h:820
ObjectGuid GetPetGUID() const
Definition: Unit.h:1232
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:580
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:274
bool AllowMount
Definition: Map.h:277
bool IsDungeon() const
Definition: Map.h:448
bool IsBattlegroundOrArena() const
Definition: Map.h:456
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3319
uint32 GetId() const
Definition: Map.h:379
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:263
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:776
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7744
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8356
SpellCastResult CheckItems()
Definition: Spell.cpp:7176
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7131
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6848
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8555
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7045
bool HasGlobalCooldown() const
Definition: Spell.cpp:8827
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1433
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2040
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2395
bool IsSelfCast() const
Definition: SpellInfo.cpp:1089
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1231
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1488
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1986
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2322
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2054
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1032
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1936
Definition: DBCStructure.h:518
Definition: DBCStructure.h:1020
Definition: DBCStructure.h:1324
bool IsDungeon() const
Definition: DBCStructure.h:1350
Definition: DBCStructure.h:1816
uint32 flags1
Definition: DBCStructure.h:1821
Definition: DBCStructure.h:1908
uint32 Category
Definition: DBCStructure.h:1910
Definition: DBCStructure.h:2063
uint32 m_flags
Definition: DBCStructure.h:2065

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6849{
6850 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6852 return SPELL_CAST_OK;
6853
6854 uint8 school_immune = 0;
6855 uint32 mechanic_immune = 0;
6856 uint32 dispel_immune = 0;
6857
6858 // Check if the spell grants school or mechanic immunity.
6859 // We use bitmasks so the loop is done only once and not on every aura check below.
6861 {
6862 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6863 {
6864 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6865 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6866 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6867 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6868 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6869 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6870 }
6871 // immune movement impairment and loss of control
6872 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6873 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6875 }
6876
6878
6879 // Glyph of Pain Suppression
6880 // there is no other way to handle it
6881 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6882 usableInStun = false;
6883
6884 // Check whether the cast should be prevented by any state you might have.
6885 SpellCastResult prevented_reason = SPELL_CAST_OK;
6886 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6887 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6888
6889 // Xinef: if spell is triggered check preventionType only
6890 if (!preventionOnly)
6891 {
6892 if (unitflag & UNIT_FLAG_STUNNED)
6893 {
6894 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6895 if (usableInStun)
6896 {
6897 bool foundNotStun = false;
6898 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6899 // Barkskin should skip sleep effects, sap and fears
6900 if (m_spellInfo->Id == 22812)
6901 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6902 // Hand of Freedom, can be used while sapped
6903 if (m_spellInfo->Id == 1044)
6904 mask |= 1 << MECHANIC_SAPPED;
6906 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6907 {
6908 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6909 {
6910 foundNotStun = true;
6911 break;
6912 }
6913 }
6914 if (foundNotStun)
6915 prevented_reason = SPELL_FAILED_STUNNED;
6916 }
6917 else
6918 prevented_reason = SPELL_FAILED_STUNNED;
6919 }
6921 prevented_reason = SPELL_FAILED_CONFUSED;
6923 prevented_reason = SPELL_FAILED_FLEEING;
6924 }
6925
6926 // Xinef: if there is no prevented_reason, check prevention types
6927 if (prevented_reason == SPELL_CAST_OK)
6928 {
6930 prevented_reason = SPELL_FAILED_SILENCED;
6932 prevented_reason = SPELL_FAILED_PACIFIED;
6933 }
6934
6935 // Attr must make flag drop spell totally immune from all effects
6936 if (prevented_reason != SPELL_CAST_OK)
6937 {
6938 if (school_immune || mechanic_immune || dispel_immune)
6939 {
6940 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6942 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6943 {
6944 Aura const* aura = itr->second->GetBase();
6945 SpellInfo const* auraInfo = aura->GetSpellInfo();
6946 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6947 continue;
6948 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6949 continue;
6950 if (auraInfo->GetDispelMask() & dispel_immune)
6951 continue;
6952
6953 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6954 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6955 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6956 {
6957 if (AuraEffect* part = aura->GetEffect(i))
6958 {
6959 switch (part->GetAuraType())
6960 {
6962 {
6963 uint32 mask = 1 << MECHANIC_STUN;
6964 // Barkskin should skip sleep effects, sap and fears
6965 if (m_spellInfo->Id == 22812)
6966 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6967 // Hand of Freedom, can be used while sapped
6968 if (m_spellInfo->Id == 1044)
6969 mask |= 1 << MECHANIC_SAPPED;
6970
6971 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6972 return SPELL_FAILED_STUNNED;
6973 break;
6974 }
6977 return SPELL_FAILED_CONFUSED;
6978 break;
6981 return SPELL_FAILED_FLEEING;
6982 break;
6987 return SPELL_FAILED_PACIFIED;
6989 return SPELL_FAILED_SILENCED;
6990 break;
6991 default:
6992 break;
6993 }
6994 }
6995 }
6996 }
6997 }
6998 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6999 else
7000 return prevented_reason;
7001 }
7002 return SPELL_CAST_OK;
7003}
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
@ UNIT_FLAG_PACIFIED
Definition: UnitDefines.h:246
@ UNIT_FLAG_CONFUSED
Definition: UnitDefines.h:251
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:252
@ UNIT_FLAG_SILENCED
Definition: UnitDefines.h:242
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1554
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1555
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:584
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:585
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:435
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1338
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1335
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1355
@ MECHANIC_HORROR
Definition: SharedDefines.h:1349
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1361
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1057
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:975
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1053
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:983
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1047
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:606
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:639
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1331
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1991

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:405

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8489{
8490 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8492}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7922{
7923 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7924 {
7929 if (target->IsCreature() && target->IsVehicle())
7930 return false;
7931 if (target->IsMounted())
7932 return false;
7933 if (target->GetCharmerGUID())
7934 return false;
7935 if (int32 damage = CalculateSpellDamage(eff, target))
7936 if ((int32)target->GetLevel() > damage)
7937 return false;
7938 break;
7939 default:
7940 break;
7941 }
7942
7943 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7944 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7945 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7946 return true;
7947
7948 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7951 {
7952 return true;
7953 }
7954
7956 //Check targets for LOS visibility (except spells without range limitations)
7957 switch (m_spellInfo->Effects[eff].Effect)
7958 {
7960 // player far away, maybe his corpse near?
7961 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7962 {
7964 return false;
7965
7967 if (!corpse)
7968 return false;
7969
7970 if (target->GetGUID() != corpse->GetOwnerGUID())
7971 return false;
7972
7974 return false;
7975 }
7976 break;
7978 {
7980 {
7981 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7982 return true;
7983
7984 return false;
7985 }
7986
7988 if (!corpse)
7989 return false;
7990
7991 if (target->GetGUID() != corpse->GetOwnerGUID())
7992 return false;
7993
7995 return false;
7996
7998 return false;
7999 }
8000 break;
8002 if (!m_caster->IsPlayer() || !target->IsPlayer())
8003 return false;
8004 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8005 return false;
8006 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8007 return false;
8008 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8009 return false;
8010 break;
8011 default: // normal case
8012 {
8013 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8014 GameObject* gobCaster = nullptr;
8016 {
8018 }
8019 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8020 {
8021 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8022 {
8023 gobCaster = tempSummon->GetSummonerGameObject();
8024 }
8025 }
8026
8027 if (gobCaster)
8028 {
8029 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8030 {
8031 return true;
8032 }
8033
8034 // If spell casted by gameobject then ignore M2 models
8035 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8036 }
8037
8038 if (target != m_caster)
8039 {
8040 if (m_targets.HasDst())
8041 {
8042 float x = m_targets.GetDstPos()->GetPositionX();
8043 float y = m_targets.GetDstPos()->GetPositionY();
8044 float z = m_targets.GetDstPos()->GetPositionZ();
8045
8046 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8047 {
8048 return false;
8049 }
8050 }
8052 {
8053 return false;
8054 }
8055 }
8056 break;
8057 }
8058 }
8059
8060 return true;
8061}
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:246
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
#define sWorld
Definition: World.h:443
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:179
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:642
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:280

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7177{
7178 Player* player = m_caster->ToPlayer();
7179 if (!player)
7180 {
7181 // Non-player case: Check if creature is disarmed
7183 {
7185 }
7186
7187 return SPELL_CAST_OK;
7188 }
7189
7190 if (!m_CastItem)
7191 {
7192 if (m_castItemGUID)
7194 }
7195 else
7196 {
7197 uint32 itemid = m_CastItem->GetEntry();
7198 if (!player->HasItemCount(itemid))
7200
7201 ItemTemplate const* proto = m_CastItem->GetTemplate();
7202 if (!proto)
7204
7205 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7206 if (proto->Spells[i].SpellCharges)
7207 if (m_CastItem->GetSpellCharges(i) == 0)
7209
7210 // consumable cast item checks
7212 {
7213 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7214 SpellCastResult failReason = SPELL_CAST_OK;
7215 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7216 {
7217 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7218 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7219 continue;
7220
7221 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7222 {
7224 {
7226 continue;
7227 }
7228 else
7229 {
7230 failReason = SPELL_CAST_OK;
7231 break;
7232 }
7233 }
7234
7235 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7236 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7237 {
7238 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7239 {
7241 continue;
7242 }
7243
7244 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7246 {
7248 continue;
7249 }
7250 else
7251 {
7252 failReason = SPELL_CAST_OK;
7253 break;
7254 }
7255 }
7256 }
7257 if (failReason != SPELL_CAST_OK)
7258 return failReason;
7259 }
7260 }
7261
7262 // check target item
7264 {
7265 if (!m_caster->IsPlayer())
7267
7268 if (!m_targets.GetItemTarget())
7270
7273 }
7274 // if not item target then required item must be equipped
7275 else
7276 {
7277 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7278 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7281 }
7282
7283 // do not take reagents for these item casts
7285 {
7287 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7288 if (!checkReagents)
7289 if (Item* targetItem = m_targets.GetItemTarget())
7290 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7291 checkReagents = true;
7292
7293 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7294 if (checkReagents)
7295 {
7296 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7297 {
7298 if (m_spellInfo->Reagent[i] <= 0)
7299 continue;
7300
7301 uint32 itemid = m_spellInfo->Reagent[i];
7302 uint32 itemcount = m_spellInfo->ReagentCount[i];
7303
7304 // if CastItem is also spell reagent
7305 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7306 {
7307 ItemTemplate const* proto = m_CastItem->GetTemplate();
7308 if (!proto)
7310 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7311 {
7312 // CastItem will be used up and does not count as reagent
7313 int32 charges = m_CastItem->GetSpellCharges(s);
7314 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7315 {
7316 ++itemcount;
7317 break;
7318 }
7319 }
7320 }
7321 if (!player->HasItemCount(itemid, itemcount))
7322 return SPELL_FAILED_REAGENTS;
7323 }
7324 }
7325
7326 // check totem-item requirements (items presence in inventory)
7327 uint32 totems = 2;
7328 for (int i = 0; i < 2; ++i)
7329 {
7330 if (m_spellInfo->Totem[i] != 0)
7331 {
7332 if (player->HasItemCount(m_spellInfo->Totem[i]))
7333 {
7334 totems -= 1;
7335 continue;
7336 }
7337 }
7338 else
7339 totems -= 1;
7340 }
7341 if (totems != 0)
7342 return SPELL_FAILED_TOTEMS; //0x7C
7343
7344 // Check items for TotemCategory (items presence in inventory)
7346 for (int i = 0; i < 2; ++i)
7347 {
7348 if (m_spellInfo->TotemCategory[i] != 0)
7349 {
7351 {
7352 TotemCategory -= 1;
7353 continue;
7354 }
7355 }
7356 else
7357 TotemCategory -= 1;
7358 }
7359 if (TotemCategory != 0)
7360 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7361 }
7362
7363 // special checks for spell effects
7364 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7365 {
7366 switch (m_spellInfo->Effects[i].Effect)
7367 {
7370 {
7371 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7372 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7373 if (target->IsPlayer() && !IsTriggered())
7374 {
7375 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7376 // so we need to make sure there is at least one free space in the player's inventory
7378 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7379 {
7380 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7382 }
7383
7384 if (m_spellInfo->Effects[i].ItemType)
7385 {
7386 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7387 if (!itemTemplate)
7389
7390 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7391 ItemPosCountVec dest;
7392 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7393 if (msg != EQUIP_ERR_OK)
7394 {
7396 if (!itemTemplate->ItemLimitCategory)
7397 {
7398 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7400 }
7401 else
7402 {
7403 // Conjure Food/Water/Refreshment spells
7406 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7407 {
7408 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7410 }
7411 else
7412 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7413
7415 }
7416 }
7417 }
7418 }
7419 break;
7420 }
7422 {
7423 if (player->GetFreeInventorySpace() == 0)
7424 {
7425 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7427 }
7428 break;
7429 }
7431 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7433 {
7434 // cannot enchant vellum for other player
7437 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7440 ItemPosCountVec dest;
7441 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7442 if (msg != EQUIP_ERR_OK)
7443 {
7444 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7446 }
7447 }
7448 [[fallthrough]];
7450 {
7451 Item* targetItem = m_targets.GetItemTarget();
7452 if (!targetItem)
7454
7455 // xinef: required level has to be checked also! Exploit fix
7456 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7457 return SPELL_FAILED_LOWLEVEL;
7458
7459 bool isItemUsable = false;
7460 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7461 {
7462 ItemTemplate const* proto = targetItem->GetTemplate();
7463 if (proto->Spells[e].SpellId && (
7466 {
7467 isItemUsable = true;
7468 break;
7469 }
7470 }
7471
7472 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7473 // do not allow adding usable enchantments to items that have use effect already
7474 if (enchantEntry)
7475 {
7476 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7477 {
7478 switch (enchantEntry->type[s])
7479 {
7481 if (isItemUsable)
7483 break;
7485 {
7486 uint32 numSockets = 0;
7487 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7488 if (targetItem->GetTemplate()->Socket[socket].Color)
7489 ++numSockets;
7490
7491 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7493 break;
7494 }
7495 }
7496 }
7497 }
7498
7499 // Not allow enchant in trade slot for some enchant type
7500 if (targetItem->GetOwner() != m_caster)
7501 {
7502 if (!enchantEntry)
7503 return SPELL_FAILED_ERROR;
7504 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7506 }
7507 break;
7508 }
7510 {
7511 Item* item = m_targets.GetItemTarget();
7512 if (!item)
7514 // Not allow enchant in trade slot for some enchant type
7515 if (item->GetOwner() != m_caster)
7516 {
7517 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7518 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7519 if (!pEnchant)
7520 return SPELL_FAILED_ERROR;
7521 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7523 }
7524
7525 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7526 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7527 {
7529 return SPELL_FAILED_LOWLEVEL;
7530 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7532 }
7533
7534 break;
7535 }
7537 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7538 break;
7540 {
7541 if (!m_targets.GetItemTarget())
7543
7544 // prevent disenchanting in trade slot
7547
7548 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7549 if (!itemProto)
7551
7552 uint32 item_quality = itemProto->Quality;
7553 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7554 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7555 if (item_disenchantskilllevel == uint32(-1))
7557 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7559 if (item_quality > 4 || item_quality < 2)
7561 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7563 if (!itemProto->DisenchantID)
7565 break;
7566 }
7568 {
7569 if (!m_targets.GetItemTarget())
7571 //ensure item is a prospectable ore
7574 //prevent prospecting in trade slot
7577 //Check for enough skill in jewelcrafting
7578 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7579 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7581 //make sure the player has the required ores in inventory
7582 if (m_targets.GetItemTarget()->GetCount() < 5)
7584
7587
7588 break;
7589 }
7591 {
7592 if (!m_targets.GetItemTarget())
7594 //ensure item is a millable herb
7597 //prevent milling in trade slot
7600 //Check for enough skill in inscription
7601 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7602 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7604 //make sure the player has the required herbs in inventory
7605 if (m_targets.GetItemTarget()->GetCount() < 5)
7607
7610
7611 break;
7612 }
7615 {
7616 if (!m_caster->IsPlayer())
7618
7620 break;
7621
7623 if (!pItem || pItem->IsBroken())
7625
7626 switch (pItem->GetTemplate()->SubClass)
7627 {
7629 {
7630 uint32 ammo = pItem->GetEntry();
7631 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7632 return SPELL_FAILED_NO_AMMO;
7633 };
7634 break;
7638 {
7640 if (!ammo)
7641 {
7642 // Requires No Ammo
7643 if (m_caster->HasAura(46699))
7644 break; // skip other checks
7645
7646 return SPELL_FAILED_NO_AMMO;
7647 }
7648
7649 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7650 if (!ammoProto)
7651 return SPELL_FAILED_NO_AMMO;
7652
7653 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7654 return SPELL_FAILED_NO_AMMO;
7655
7656 // check ammo ws. weapon compatibility
7657 switch (pItem->GetTemplate()->SubClass)
7658 {
7661 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7662 return SPELL_FAILED_NO_AMMO;
7663 break;
7665 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7666 return SPELL_FAILED_NO_AMMO;
7667 break;
7668 default:
7669 return SPELL_FAILED_NO_AMMO;
7670 }
7671
7672 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7673 {
7675 return SPELL_FAILED_NO_AMMO;
7676 }
7677 };
7678 break;
7680 break;
7681 default:
7682 break;
7683 }
7684 break;
7685 }
7687 {
7688 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7689 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7690
7691 if (!pProto)
7693
7694 if (Item* pitem = player->GetItemByEntry(item_id))
7695 {
7696 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7697 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7699 }
7700 break;
7701 }
7702 default:
7703 break;
7704 }
7705 }
7706
7707 // check weapon presence in slots for main/offhand weapons
7708 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7709 {
7710 // main hand weapon required
7712 {
7714
7715 // skip spell if no weapon in slot or broken
7716 if (!item || item->IsBroken())
7718
7719 // skip spell if weapon not fit to triggered spell
7722 }
7723
7724 // offhand hand weapon required
7726 {
7728
7729 // skip spell if no weapon in slot or broken
7730 if (!item || item->IsBroken())
7732
7733 // skip spell if weapon not fit to triggered spell
7736 }
7737
7739 }
7740
7741 return SPELL_CAST_OK;
7742}
std::int8_t int8
Definition: Define.h:105
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1638
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1837
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:338
bool IsArmorVellum() const
Definition: Item.h:339
Player * GetOwner() const
Definition: Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:885
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Color
Definition: ItemTemplate.h:602
Definition: ItemTemplate.h:619
uint32 DisenchantID
Definition: ItemTemplate.h:690
uint32 Quality
Definition: ItemTemplate.h:626
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 RequiredLevel
Definition: ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 SubClass
Definition: ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12517
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:468
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3371
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:657
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:853
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12562
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4023
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1274
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:1066
bool IsFullHealth() const
Definition: Unit.h:872
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:892
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21291
uint32 GetPower(Powers power) const
Definition: Unit.h:891
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1840
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1843
uint32 slot
Definition: DBCStructure.h:1850

References BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6813{
6814 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6816
6817 // dead owner (pets still alive when owners ressed?)
6818 if (Unit* owner = m_caster->GetCharmerOrOwner())
6819 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6821
6822 if (!target && m_targets.GetUnitTarget())
6823 target = m_targets.GetUnitTarget();
6824
6826 {
6827 if (!target)
6829 m_targets.SetUnitTarget(target);
6830 }
6831
6832 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6834
6835 // cooldown
6836 if (Creature const* creatureCaster = m_caster->ToCreature())
6837 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6839
6840 // Check if spell is affected by GCD
6844
6845 return CheckCast(true);
6846}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: CharmInfo.cpp:405
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:238
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2400
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7132{
7133 // item cast not used power
7134 if (m_CastItem)
7135 return SPELL_CAST_OK;
7136
7137 //While .cheat power is enabled dont check if we need power to cast the spell
7138 if (m_caster->IsPlayer())
7139 {
7141 {
7142 return SPELL_CAST_OK;
7143 }
7144 }
7145
7146 // health as power used - need check health amount
7148 {
7151 return SPELL_CAST_OK;
7152 }
7153 // Check valid power type
7155 {
7156 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7157 return SPELL_FAILED_UNKNOWN;
7158 }
7159
7160 //check rune cost only if a spell has PowerType == POWER_RUNE
7162 {
7164 if (failReason != SPELL_CAST_OK)
7165 return failReason;
7166 }
7167
7168 // Check power amount
7171 return SPELL_FAILED_NO_POWER;
7172 else
7173 return SPELL_CAST_OK;
7174}
PowerType
Definition: VehicleDefines.h:29
@ CHEAT_POWER
Definition: Player.h:1002
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
uint32 GetHealth() const
Definition: Unit.h:869
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5406
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7046{
7047 // Don't check for instant cast spells
7048 if (!strict && m_casttime == 0)
7049 return SPELL_CAST_OK;
7050
7051 uint32 range_type = 0;
7052
7054 {
7055 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7056 // these are triggered by other spells - possibly we should omit range check in that case?
7057 if (m_spellInfo->RangeEntry->ID == 1)
7058 return SPELL_CAST_OK;
7059
7060 range_type = m_spellInfo->RangeEntry->Flags;
7061 }
7062
7063 Unit* target = m_targets.GetUnitTarget();
7064 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7065 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7066
7067 // xinef: hack for npc shooters
7068 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7069 range_type = SPELL_RANGE_RANGED;
7070
7071 if (Player* modOwner = m_caster->GetSpellModOwner())
7072 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7073
7074 // xinef: dont check max_range to strictly after cast
7075 if (range_type != SPELL_RANGE_MELEE && !strict)
7076 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7077
7078 if (target)
7079 {
7080 if (target != m_caster)
7081 {
7082 // Xinef: Spells with 5yd range can hit target 9yd away?
7083 if (range_type == SPELL_RANGE_MELEE)
7084 {
7085 float real_max_range = max_range;
7086 if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7087 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7088 else
7089 real_max_range -= 2 * MIN_MELEE_REACH;
7090
7091 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7093 }
7094 else if (!m_caster->IsWithinCombatRange(target, max_range))
7095 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7096
7098 {
7099 if (m_caster->IsWithinMeleeRange(target))
7101 }
7102
7103 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7105 }
7106
7107 // Xinef: check min range for self casts
7108 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7110 }
7111
7112 if (GameObject* goTarget = m_targets.GetGOTarget())
7113 {
7114 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7115 {
7117 }
7118 }
7119
7120 if (m_targets.HasDst() && !m_targets.HasTraj())
7121 {
7122 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7124 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7126 }
7127
7128 return SPELL_CAST_OK;
7129}
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELLMOD_RANGE
Definition: SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:125
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1295
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:648
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15131
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:664
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15111
bool IsWalking() const
Definition: Unit.h:1709
Unit * GetCaster() const
Definition: Spell.h:573
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1796
uint32 ID
Definition: DBCStructure.h:1793

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5407{
5408 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5409 return SPELL_CAST_OK;
5410
5411 if (!m_caster->IsPlayer())
5412 return SPELL_CAST_OK;
5413
5414 Player* player = m_caster->ToPlayer();
5415 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5416 if (player->GetCommandStatus(CHEAT_POWER))
5417 {
5418 return SPELL_CAST_OK;
5419 }
5420
5422 return SPELL_CAST_OK;
5423
5424 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5425
5426 if (!src)
5427 return SPELL_CAST_OK;
5428
5429 if (src->NoRuneCost())
5430 return SPELL_CAST_OK;
5431
5432 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5433
5434 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5435 {
5436 runeCost[i] = src->RuneCost[i];
5437 if (Player* modOwner = m_caster->GetSpellModOwner())
5438 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5439 }
5440
5441 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5442
5443 for (uint32 i = 0; i < MAX_RUNES; ++i)
5444 {
5445 RuneType rune = player->GetCurrentRune(i);
5446 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5447 runeCost[rune]--;
5448 }
5449
5450 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5451 if (runeCost[i] > 0)
5452 runeCost[RUNE_DEATH] += runeCost[i];
5453
5454 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5455 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5456
5457 return SPELL_CAST_OK;
5458}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
RuneType
Definition: Player.h:408
@ RUNE_DEATH
Definition: Player.h:412
@ NUM_RUNE_TYPES
Definition: Player.h:413
#define MAX_RUNES
Definition: Player.h:398
@ SPELLMOD_COST
Definition: SpellDefines.h:90
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2490
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1280
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2489
Definition: DBCStructure.h:1804
uint32 RuneCost[3]
Definition: DBCStructure.h:1806
bool NoRuneCost() const
Definition: DBCStructure.h:1809

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8710{
8711 // Skip if there are not any script
8712 if (!m_loadedScripts.size())
8713 return true;
8714
8715 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8716 {
8717 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8718 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8719 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8720 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8721 return false;
8722
8723 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8724 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8725 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8726 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8727 return false;
8728 }
8729 return true;
8730}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7745{
7746 // check spell focus object
7748 {
7750 Cell cell(p);
7751
7752 GameObject* ok = nullptr;
7755
7757 Map& map = *m_caster->GetMap();
7758 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7759
7760 if (!ok)
7762
7763 focusObject = ok; // game object found in range
7764 }
7765 return SPELL_CAST_OK;
7766}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:101
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:45
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:313
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:873
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:164
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:366

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2371{
2372 m_UniqueTargetInfo.clear();
2373 m_UniqueGOTargetInfo.clear();
2374 m_UniqueItemInfo.clear();
2375 m_delayMoment = 0;
2377}
uint64 m_delayTrajectory
Definition: Spell.h:640

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7769{
7770 if (!m_caster)// || !m_caster->IsPlayer())
7771 return;
7772
7773 //if (m_spellState == SPELL_STATE_DELAYED)
7774 // return; // spell is active and can't be time-backed
7775
7776 if (isDelayableNoMore()) // Spells may only be delayed twice
7777 return;
7778
7780 return;
7781
7782 // spells not loosing casting time (slam, dynamites, bombs..)
7783 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7784 // return;
7785
7786 //check pushback reduce
7787 int32 delaytime = 500; // spellcasting delay is normally 500ms
7788 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7791 if (delayReduce >= 100)
7792 return;
7793
7794 AddPct(delaytime, -delayReduce);
7795
7796 if (m_timer + delaytime > m_casttime)
7797 {
7798 delaytime = m_casttime - m_timer;
7800 }
7801 else
7802 m_timer += delaytime;
7803
7804 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7805
7806 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7807 data << m_caster->GetPackGUID();
7808 data << uint32(delaytime);
7809
7810 m_caster->SendMessageToSet(&data, true);
7811}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:85
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9729
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5888
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:628

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7814{
7816 return;
7817
7818 if (isDelayableNoMore()) // Spells may only be delayed twice
7819 return;
7820
7822 return;
7823
7824 //check pushback reduce
7825 // should be affected by modifiers, not take the dbc duration.
7827
7828 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7829 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7832 if (delayReduce >= 100)
7833 return;
7834
7835 AddPct(delaytime, -delayReduce);
7836
7837 if (m_timer <= delaytime)
7838 {
7839 delaytime = m_timer;
7840 m_timer = 0;
7841 }
7842 else
7843 m_timer -= delaytime;
7844
7845 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7846
7847 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7848 if ((*ihit).missCondition == SPELL_MISS_NONE)
7849 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7850 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7851
7852 // partially interrupt persistent area auras
7854 dynObj->Delay(delaytime);
7855
7857}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6106
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2337

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8297{
8298 Unit* unit = nullptr;
8299 // In case spell hit target, do all effect on that target
8300 if (targetInfo.missCondition == SPELL_MISS_NONE)
8301 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8302 // In case spell reflect from target, do all effect on caster (if hit)
8303 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8304 unit = m_caster;
8305 if (!unit)
8306 return;
8307
8308 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8309 {
8310 if (targetInfo.effectMask & (1 << i))
8311 {
8312 m_damage = 0;
8313 m_healing = 0;
8314
8315 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8316
8317 if (m_damage > 0)
8318 {
8319 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8320 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8321 {
8323 if (m_caster->IsPlayer())
8324 {
8325 uint32 targetAmount = m_UniqueTargetInfo.size();
8326 if (targetAmount > 10)
8327 m_damage = m_damage * 10 / targetAmount;
8328 }
8329 }
8330 }
8331
8332 if (m_applyMultiplierMask & (1 << i))
8333 {
8335 m_damageMultipliers[i] *= multiplier[i];
8336 }
8337 targetInfo.damage += m_damage;
8338 }
8339 }
8340
8341 // xinef: totem's inherit owner crit chance and dancing rune weapon
8342 Unit* caster = m_caster;
8343 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8344 {
8345 if (Unit* owner = m_caster->GetOwner())
8346 caster = owner;
8347 }
8348 else if (m_originalCaster)
8349 caster = m_originalCaster;
8350
8351 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8352 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8353 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8354}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12033
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11958
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:20369
uint32 SchoolMask
Definition: SpellInfo.h:392

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), ObjectAccessor::GetUnit(), HandleEffects(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3341{
3342 if (target->processed) // Check target
3343 return;
3344 target->processed = true; // Target checked in apply effects procedure
3345
3346 uint32 effectMask = target->effectMask;
3347 if (!effectMask)
3348 return;
3349
3350 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3351 if (!go)
3352 return;
3353
3356
3357 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3358 if (effectMask & (1 << effectNumber))
3359 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3360
3361 // xinef: inform ai about spellhit
3363
3365
3367}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:66
GameObjectAI * AI() const
Definition: GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8628
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8641
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8654

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3370{
3371 uint32 effectMask = target->effectMask;
3372 if (!target->item || !effectMask)
3373 return;
3374
3377
3378 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3379 if (effectMask & (1 << effectNumber))
3380 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3381
3383
3385}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2609{
2610 if (!target || target->processed)
2611 return;
2612
2613 target->processed = true; // Target checked in apply effects procedure
2614
2615 // Get mask of effects for target
2616 uint8 mask = target->effectMask;
2617
2618 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2619 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2620 return;
2621
2622 if (!effectUnit || m_spellInfo->Id == 45927)
2623 {
2624 uint8 farMask = 0;
2625 // create far target mask
2626 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2627 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2628 if ((1 << i) & mask)
2629 farMask |= (1 << i);
2630
2631 if (!farMask)
2632 return;
2633 // find unit in world
2634 // Xinef: FindUnit Access without Map check!!! Intended
2635 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2636 if (!effectUnit)
2637 return;
2638
2639 // do far effects on the unit
2640 // can't use default call because of threading, do stuff as fast as possible
2641 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2642 if (farMask & (1 << i))
2643 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2644 return;
2645 }
2646
2647 if (effectUnit->IsAlive() != target->alive)
2648 return;
2649
2650 // Xinef: absorb delayed projectiles for 500ms
2652 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2653 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2654 )
2655 return; // No missinfo in that case
2656
2657 // Get original caster (if exist) and calculate damage/healing from him data
2659
2660 // Skip if m_originalCaster not avaiable
2661 if (!caster)
2662 return;
2663
2664 SpellMissInfo missInfo = target->missCondition;
2665
2666 // Need init unitTarget by default unit (can changed in code on reflect)
2667 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2668 unitTarget = effectUnit;
2669
2670 // Reset damage/healing counter
2671 m_damage = target->damage;
2672 m_healing = -target->damage;
2673
2674 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2675
2678
2679 //Spells with this flag cannot trigger if effect is casted on self
2681 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2682 Unit* spellHitTarget = nullptr;
2683
2684 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2685 spellHitTarget = unitTarget;
2686 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2687 {
2688 missInfo = target->reflectResult;
2689 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2690 {
2691 spellHitTarget = m_caster;
2693 if (m_caster->IsCreature())
2695 }
2696 }
2697
2698 if (spellHitTarget)
2699 {
2700 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2701 if (missInfo2 != SPELL_MISS_NONE)
2702 {
2703 if (missInfo2 != SPELL_MISS_MISS)
2704 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2705 m_damage = 0;
2706 spellHitTarget = nullptr;
2707
2708 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2709 if (missInfo2 == SPELL_MISS_EVADE)
2710 missInfo = SPELL_MISS_EVADE;
2711 }
2712 }
2713
2714 // Do not take combo points on dodge and miss
2715 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2716 {
2717 m_needComboPoints = false;
2718 // Restore spell mods for a miss/dodge/parry Cold Blood
2720 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2721 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2722 }
2723
2724 // Fill base trigger info
2725 uint32 procAttacker = m_procAttacker;
2726 uint32 procVictim = m_procVictim;
2727 uint32 procEx = m_procEx;
2728
2729 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2730 if (canEffectTrigger && !procAttacker && !procVictim)
2731 {
2732 bool positive = true;
2733 if (m_damage > 0)
2734 positive = false;
2735 else if (!m_healing)
2736 {
2737 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2738 // If at least one effect negative spell is negative hit
2739 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2740 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2741 {
2742 positive = false;
2743 break;
2744 }
2745 }
2746 switch (m_spellInfo->DmgClass)
2747 {
2749 if (positive)
2750 {
2753 }
2754 else
2755 {
2758 }
2759 break;
2761 if (positive)
2762 {
2765 }
2766 else
2767 {
2770 }
2771 break;
2772 }
2773 }
2775
2776 // All calculated do it!
2777 // Do healing and triggers
2778 if (m_healing > 0)
2779 {
2780 bool crit = target->crit;
2781 uint32 addhealth = m_healing;
2782
2783 if (crit)
2784 {
2785 procEx |= PROC_EX_CRITICAL_HIT;
2786 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2787 }
2788 else
2789 procEx |= PROC_EX_NORMAL_HIT;
2790
2791 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2792
2793 // Xinef: override with forced crit, only visual result
2794 if (GetSpellValue()->ForcedCritResult)
2795 {
2796 crit = true;
2797 procEx |= PROC_EX_CRITICAL_HIT;
2798 }
2799
2800 int32 gain = caster->HealBySpell(healInfo, crit);
2801 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2802 m_healing = gain;
2803
2804 // Xinef: if heal acutally healed something, add no overheal flag
2805 if (m_healing)
2806 procEx |= PROC_EX_NO_OVERHEAL;
2807
2808 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2809 if (canEffectTrigger)
2810 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2811 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2812 }
2813 // Do damage and triggers
2814 else if (m_damage > 0)
2815 {
2817
2818 // Fill base damage struct (unitTarget - is real spell target)
2820
2821 // Add bonuses and fill damageInfo struct
2822 // Dancing Rune Weapon...
2823 if (m_caster->GetEntry() == 27893)
2824 {
2825 if (Unit* owner = m_caster->GetOwner())
2826 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2827 }
2828 else
2829 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2830
2831 // xinef: override miss info after absorb / block calculations
2832 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2833 {
2834 //if (damageInfo.absorb > 0)
2835 // missInfo = SPELL_MISS_ABSORB;
2836 if (damageInfo.blocked)
2837 missInfo = SPELL_MISS_BLOCK;
2838 }
2839
2840 // Xinef: override with forced crit, only visual result
2841 if (GetSpellValue()->ForcedCritResult)
2842 {
2843 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2844 }
2845
2846 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2847
2848 // xinef: health leech handling
2850 {
2851 uint8 effIndex = EFFECT_0;
2852 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2853 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2854 break;
2855
2856 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2857
2858 // get max possible damage, don't count overkill for heal
2859 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2860
2861 if (m_caster->IsAlive())
2862 {
2863 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2864 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2865
2866 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2867 m_caster->HealBySpell(healInfo);
2868 }
2869 }
2870
2871 // Send log damage message to client
2872 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2873 // Xinef: send info to target about reflect
2874 if (reflectedSpell)
2875 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2876
2877 procEx |= createProcExtendMask(&damageInfo, missInfo);
2878 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2879
2880 caster->DealSpellDamage(&damageInfo, true, this);
2881
2882 // do procs after damage, eg healing effects
2883 // no need to check if target is alive, done in procdamageandspell
2884
2885 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2886 if (canEffectTrigger)
2887 {
2888 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2889 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2890 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2891
2894 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2895 }
2896
2897 m_damage = damageInfo.damage;
2898 }
2899 // Passive spell hits/misses or active spells only misses (only triggers)
2900 else
2901 {
2902 // Fill base damage struct (unitTarget - is real spell target)
2904 procEx |= createProcExtendMask(&damageInfo, missInfo);
2905 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2906 if (canEffectTrigger)
2907 {
2908 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2909 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2910 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2911
2912 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2913 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2917 }
2918
2919 // Failed Pickpocket, reveal rogue
2921 {
2925 }
2926 }
2927
2928 if (m_caster)
2929 {
2931 {
2934
2935 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2936 if (effectUnit->IsInCombatWith(m_caster))
2937 {
2938 if (Creature* creature = effectUnit->ToCreature())
2939 {
2940 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2941 {
2942 creature->SetLootRecipient(m_caster);
2943 }
2944 }
2945 }
2946
2947 // Unsure if there are more spells that are not supposed to stop enemy from
2948 // regenerating HP from food, so for now it stays as an ID.
2949 const uint32 SPELL_PREMEDITATION = 14183;
2950 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2951 {
2952 if (!effectUnit->IsStandState())
2953 {
2955 }
2956 }
2957 }
2958 }
2959
2960 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2962 {
2963 m_caster->SetInCombatWith(effectUnit);
2964 }
2965
2966 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2968 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2969
2970 if (spellHitTarget)
2971 {
2972 //AI functions
2973 if (spellHitTarget->IsCreature())
2974 {
2975 if (spellHitTarget->ToCreature()->IsAIEnabled)
2976 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2977 }
2978
2980 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2981
2982 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2983 DoTriggersOnSpellHit(spellHitTarget, mask);
2984
2985 // if target is fallged for pvp also flag caster if a player
2986 // xinef: do not flag spells with aura bind sight (no special attribute)
2987 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2989 {
2990 m_caster->ToPlayer()->UpdatePvP(true);
2991 }
2992
2994 }
2995}
@ NODAMAGE
Definition: Unit.h:252
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:249
@ HEAL
Definition: Unit.h:251
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:15959
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:53
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1536
SpellMissInfo
Definition: SharedDefines.h:1518
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1522
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1527
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1521
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1520
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1524
@ SPELL_ATTR4_SUPRESS_WEAPON_PROCS
Definition: SharedDefines.h:553
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:145
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:142
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3805
CreatureAI * AI() const
Definition: Creature.h:143
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9935
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7199
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1480
Definition: Unit.h:330
Definition: Unit.h:373
Definition: Unit.h:489
uint32 m_lastSanctuaryTime
Definition: Unit.h:1812
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1438
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6423
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6256
bool CanProc()
Definition: Unit.h:1673
bool IsPvP() const
Definition: Unit.h:965
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12416
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13545
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11208
bool IsStandState() const
Definition: Unit.cpp:16685
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21013
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:843
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14087
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12285
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6288
bool IsAIEnabled
Definition: Unit.h:1818
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:1020
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12534
void SetStandState(uint8 state)
Definition: Unit.cpp:16691
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5159
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:800
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1295
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:215
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8732
SpellValue const * GetSpellValue()
Definition: Spell.h:583
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2997
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3263
uint32 AttributesEx3
Definition: SpellInfo.h:327
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition: SpellInfo.cpp:1697
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1024
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1241

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_SUPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1633{
1634 if (!unitTarget)
1635 return;
1636
1637 Player* player = unitTarget->ToPlayer();
1638 if (!player)
1639 {
1640 return;
1641 }
1642
1643 uint32 newitemid = itemId;
1644
1645 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1646 if (!pProto)
1647 {
1648 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1649 return;
1650 }
1651
1652 uint32 addNumber = damage;
1653
1654 // bg reward have some special in code work
1655 bool SelfCast = true;
1656 switch (m_spellInfo->Id)
1657 {
1662 case SPELL_WS_MARK_TIE:
1665 SelfCast = true;
1666 break;
1668 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1669 addNumber = 3;
1670 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1671 addNumber = 2;
1672 else
1673 addNumber = 1;
1674 SelfCast = true;
1675 break;
1676 }
1677
1678 if (addNumber < 1)
1679 addNumber = 1;
1680 if (addNumber > pProto->GetMaxStackSize())
1681 addNumber = pProto->GetMaxStackSize();
1682
1683 /* == gem perfection handling == */
1684
1685 // the chance of getting a perfect result
1686 float perfectCreateChance = 0.0f;
1687
1688 // the resulting perfect item if successful
1689 uint32 perfectItemType = itemId;
1690
1691 // get perfection capability and chance
1692 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1693 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1694 newitemid = perfectItemType; // the perfect item replaces the regular one
1695
1696 /* == gem perfection handling over == */
1697
1698 /* == profession specialization handling == */
1699
1700 // init items_count to 1, since 1 item will be created regardless of specialization
1701 int32 itemsCount = 1;
1702 float additionalCreateChance = 0.0f;
1703 int32 additionalMaxNum = 0;
1704 // get the chance and maximum number for creating extra items
1705 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1706 {
1707 // roll with this chance till we roll not to create or we create the max num
1708 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1709 ++itemsCount;
1710 }
1711
1712 // really will be created more items
1713 addNumber *= itemsCount;
1714
1715 /* == profession specialization handling over == */
1716
1717 // can the player store the new item?
1718 ItemPosCountVec dest;
1719 uint32 no_space = 0;
1720 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1721 if (msg != EQUIP_ERR_OK)
1722 {
1723 // convert to possible store amount
1725 addNumber -= no_space;
1726 else
1727 {
1728 // if not created by another reason from full inventory or unique items amount limitation
1729 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1730 return;
1731 }
1732 }
1733
1734 if (addNumber)
1735 {
1736 // create the new item and store it
1737 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1738
1739 // was it successful? return error if not
1740 if (!pItem)
1741 {
1742 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1743 return;
1744 }
1745
1746 // set the "Crafted by ..." property of the item
1747 if (pItem->GetTemplate()->HasSignature())
1748 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1749
1750 // send info to the client
1751 player->SendNewItem(pItem, addNumber, true, SelfCast);
1752
1753 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1754
1755 // we succeeded in creating at least one item, so a levelup is possible
1756 if (SelfCast)
1758 }
1759}
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:106
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:110
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:107
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:108
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:114
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:111
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
bool HasSignature() const
Definition: ItemTemplate.h:698
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:781
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4752
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2526

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2998{
2999 if (!unit || !effectMask)
3000 return SPELL_MISS_EVADE;
3001
3002 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3003 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3004 {
3005 return SPELL_MISS_IMMUNE;
3006 }
3007
3008 // disable effects to which unit is immune
3009 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3010 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3011 {
3012 if (effectMask & (1 << effectNumber))
3013 {
3014 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3015 effectMask &= ~(1 << effectNumber);
3016 // Xinef: Buggs out polymorph
3017 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3018 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3019 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3020 {
3021 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3022 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3023
3024 if (debuff_resist_chance > 0)
3025 if (irand(0,10000) <= (debuff_resist_chance * 100))
3026 {
3027 effectMask &= ~(1 << effectNumber);
3028 returnVal = SPELL_MISS_RESIST;
3029 }
3030 }*/
3031 }
3032 }
3033 if (!effectMask)
3034 return returnVal;
3035
3036 if (unit->IsPlayer())
3037 {
3041 }
3042
3043 if (m_caster->IsPlayer())
3044 {
3047 }
3048
3049 if (m_caster != unit)
3050 {
3051 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3052 // Xinef: Also check evade state
3053 if (m_spellInfo->Speed > 0.0f)
3054 {
3055 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3056 return SPELL_MISS_EVADE;
3057
3059 return SPELL_MISS_EVADE;
3060 }
3061
3062 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3063 {
3065 }
3066 else if (m_caster->IsFriendlyTo(unit))
3067 {
3068 // for delayed spells ignore negative spells (after duel end) for friendly targets
3070 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3071 return SPELL_MISS_EVADE;
3072
3073 // assisting case, healing and resurrection
3075 {
3078 m_caster->ToPlayer()->UpdatePvP(true);
3079 }
3080
3081 // xinef: triggered spells should not prolong combat
3083 {
3084 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3085 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3086 }
3087 }
3088 }
3089
3090 uint8 aura_effmask = 0;
3091 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3092 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3093 aura_effmask |= 1 << i;
3094
3095 Unit* originalCaster = GetOriginalCaster();
3096 if (!originalCaster)
3097 originalCaster = m_caster;
3098
3099 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3100 // Xinef: Do not increase diminishing level for self cast
3102 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3104 {
3107
3108 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3109
3110 // Increase Diminishing on unit, current informations for actually casts will use values above
3111 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3113 {
3114 // Do not apply diminish return if caster is NPC
3116 {
3118 }
3119 }
3120 }
3121
3123 {
3125 }
3126
3127 if (aura_effmask)
3128 {
3129 // Select rank for aura with level requirements only in specific cases
3130 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3131 SpellInfo const* aurSpellInfo = m_spellInfo;
3132 int32 basePoints[3];
3133 if (scaleAura)
3134 {
3136 ASSERT(aurSpellInfo);
3137 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3138 {
3139 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3140 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3141 {
3142 aurSpellInfo = m_spellInfo;
3143 break;
3144 }
3145 }
3146 }
3147
3148 if (m_originalCaster)
3149 {
3150 bool refresh = false;
3152 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3153 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3154
3155 // xinef: if aura was not refreshed, add proc ex
3156 if (!refresh)
3158
3159 if (m_spellAura)
3160 {
3161 // Prevent aura application if target is banished and immuned
3164 {
3166 return SPELL_MISS_IMMUNE;
3167 }
3168
3169 // Set aura stack amount to desired value
3171 {
3172 if (!refresh)
3174 else
3176 }
3177
3178 // Now Reduce spell duration using data received at spell hit
3179 int32 duration = m_spellAura->GetMaxDuration();
3180 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3181
3182 // Xinef: if unit == caster - test versus original unit if available
3183 float diminishMod = 1.0f;
3184 if (unit == m_caster && m_targets.GetUnitTarget())
3186 else
3187 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3188
3189 // unit is immune to aura if it was diminished to 0 duration
3190 if (diminishMod == 0.0f)
3191 {
3194 return SPELL_MISS_IMMUNE;
3195 bool found = false;
3196 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3197 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3198 found = true;
3199 if (!found)
3200 return SPELL_MISS_IMMUNE;
3201 }
3202 else
3203 {
3204 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3205
3206 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3208 positive = aurApp->IsPositive();
3209
3210 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3211
3212 // xinef: haste affects duration of those spells twice
3215
3216 if (m_spellValue->AuraDuration != 0)
3217 {
3218 if (m_spellAura->GetMaxDuration() != -1)
3219 {
3221 }
3222
3224 }
3225 else if (duration != m_spellAura->GetMaxDuration())
3226 {
3227 m_spellAura->SetMaxDuration(duration);
3228 m_spellAura->SetDuration(duration);
3229 }
3230
3231 // xinef: apply relic cooldown, imo best place to add this
3234
3237 }
3238 }
3239 }
3240 }
3241
3242 int8 sanct_effect = -1;
3243
3244 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3245 {
3246 // handle sanctuary effects after aura apply!
3247 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3248 {
3249 sanct_effect = effectNumber;
3250 continue;
3251 }
3252
3253 if (effectMask & (1 << effectNumber))
3254 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3255 }
3256
3257 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3258 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3259
3260 return SPELL_MISS_NONE;
3261}
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_STATE_ISOLATED
Definition: UnitDefines.h:162
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:66
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:149
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:275
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:58
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:245
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
bool isWorldBoss() const
Definition: Creature.h:123
bool IsInEvadeMode() const
Definition: Creature.h:137
uint32 flags_extra
Definition: CreatureData.h:247
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5716
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14971
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14997
uint32 GetCombatTimer() const
Definition: Unit.h:830
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12796
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17213
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:682
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15011
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14837
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1743
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13696
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1246
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5683
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12711
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12880
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12865
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10205
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13841
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1238
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:574
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2525

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, UNIT_STATE_ISOLATED, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3264{
3265 // Apply additional spell effects to target
3267 if (m_preCastSpell)
3268 {
3269 // Paladin immunity shields
3270 if (m_preCastSpell == 61988)
3271 {
3272 // Cast Forbearance
3273 m_caster->CastSpell(unit, 25771, true);
3274 // Cast Avenging Wrath Marker
3275 unit->CastSpell(unit, 61987, true);
3276 }
3277
3278 // Avenging Wrath
3279 if (m_preCastSpell == 61987)
3280 // Cast the serverside immunity shield marker
3281 m_caster->CastSpell(unit, 61988, true);
3282
3283 // Fearie Fire (Feral) - damage
3284 if (m_preCastSpell == 60089)
3285 m_caster->CastSpell(unit, m_preCastSpell, true);
3286 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3287 // Blizz seems to just apply aura without bothering to cast
3289 }
3290
3291 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3292 // this is executed after spell proc spells on target hit
3293 // spells are triggered for each hit spell target
3294 // info confirmed with retail sniffs of permafrost and shadow weaving
3295 if (!m_hitTriggerSpells.empty())
3296 {
3297 int _duration = 0;
3298 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3299 {
3300 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3301 {
3302 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3303 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3304
3305 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3306 // set duration of current aura to the triggered spell
3307 if (i->triggeredSpell->GetDuration() == -1)
3308 {
3309 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3310 {
3311 // get duration from aura-only once
3312 if (!_duration)
3313 {
3314 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3315 _duration = aur ? aur->GetDuration() : -1;
3316 }
3317 triggeredAur->SetDuration(_duration);
3318 }
3319 }
3320 }
3321 }
3322 }
3323
3324 // trigger linked auras remove/apply
3326 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3327 {
3328 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3329 if (*i < 0)
3330 {
3331 unit->RemoveAurasDueToSpell(-(*i));
3332 }
3333 else
3334 {
3335 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3336 }
3337 }
3338}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5559
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18828
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:754

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4229{
4231 return;
4232
4233 if (!gameObjTarget)
4234 return;
4235
4236 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4237 switch (action)
4238 {
4239 case GameObjectActions::AnimateCustom0:
4240 case GameObjectActions::AnimateCustom1:
4241 case GameObjectActions::AnimateCustom2:
4242 case GameObjectActions::AnimateCustom3:
4243 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4244 break;
4245 case GameObjectActions::Disturb: // What's the difference with Open?
4246 case GameObjectActions::Open:
4247 if (Unit* unitCaster = m_caster->ToUnit())
4248 gameObjTarget->Use(unitCaster);
4249 break;
4250 case GameObjectActions::OpenAndUnlock:
4251 if (Unit* unitCaster = m_caster->ToUnit())
4252 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4253 [[fallthrough]];
4254 case GameObjectActions::Unlock:
4255 case GameObjectActions::Lock:
4256 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4257 break;
4258 case GameObjectActions::Close:
4259 case GameObjectActions::Rebuild:
4261 break;
4262 case GameObjectActions::Despawn:
4264 break;
4265 case GameObjectActions::MakeInert:
4266 case GameObjectActions::MakeActive:
4267 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4268 break;
4269 case GameObjectActions::CloseAndLock:
4272 break;
4273 case GameObjectActions::Destroy:
4274 if (Unit* unitCaster = m_caster->ToUnit())
4275 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4276 break;
4277 case GameObjectActions::UseArtKit0:
4278 case GameObjectActions::UseArtKit1:
4279 case GameObjectActions::UseArtKit2:
4280 case GameObjectActions::UseArtKit3:
4281 {
4282 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4283
4284 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4285
4286 uint32 artKitValue = 0;
4287 if (templateAddon)
4288 artKitValue = templateAddon->artKits[artKitIndex];
4289
4290 if (artKitValue == 0)
4291 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4292 else
4293 gameObjTarget->SetGoArtKit(artKitValue);
4294
4295 break;
4296 }
4297 case GameObjectActions::None:
4298 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4299 break;
4300 default:
4301 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4302 break;
4303 }
4304}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:152
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
GameObjectActions
Definition: GameObject.h:77
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2150
void ResetDoorOrButton()
Definition: GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:933
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:912
void Use(Unit *user)
Definition: GameObject.cpp:1479
Definition: GameObjectData.h:664
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:670
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5743{
5745 return;
5746
5747 if (!m_caster->IsPlayer())
5748 return;
5749
5750 Player* player = m_caster->ToPlayer();
5751
5753 return;
5754
5755 // needed later
5757
5758 uint32 count = damage;
5759 if (count == 0) count = 1;
5760 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5761 {
5762 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5763 {
5764 if (m_spellInfo->Id == 45529)
5765 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5766 continue;
5767 player->SetRuneCooldown(j, 0);
5768 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5769 --count;
5770 }
5771 }
5772
5773 // Blood Tap
5774 if (m_spellInfo->Id == 45529 && count > 0)
5775 {
5776 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5777 {
5778 // Check if both runes are on cd as that is the only time when this needs to come into effect
5779 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5780 {
5781 // Should always update the rune with the lowest cd
5782 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5783 l++;
5784 player->SetRuneCooldown(l, 0);
5785 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5786 --count;
5787 }
5788 else
5789 break;
5790 }
5791 }
5792
5793 // Empower rune weapon
5794 if (m_spellInfo->Id == 47568)
5795 {
5796 // Need to do this just once
5797 if (effIndex != 0)
5798 return;
5799
5800 for (uint32 i = 0; i < MAX_RUNES; ++i)
5801 {
5802 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5803 {
5804 player->SetRuneCooldown(i, 0);
5805 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5806 }
5807 }
5808 }
5809
5810 // is needed to push through to the client that the rune is active
5811 //player->ResyncRunes(MAX_RUNES);
5812 m_caster->CastSpell(m_caster, 47804, true);
5813}
@ RUNE_FROST
Definition: Player.h:411
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2498
uint8 GetRunesState() const
Definition: Player.h:2487
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2499
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2488

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6118{
6120 return;
6121
6122 if (!unitTarget)
6123 return;
6124
6125 if (Player* player = unitTarget->ToPlayer())
6126 {
6127 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6128 }
6129}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4066{
4068 {
4069 return;
4070 }
4071
4072 if (!unitTarget || damage <= 0)
4073 {
4074 return;
4075 }
4076
4078}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:530

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4648{
4650 {
4651 return;
4652 }
4653
4654 if (!unitTarget || !unitTarget->IsAlive())
4655 {
4656 return;
4657 }
4658
4660
4662}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2748
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5114

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2693{
2695 return;
2696
2697 if (!m_caster->IsPlayer())
2698 return;
2699
2700 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2701 int32 duration = m_spellInfo->GetDuration();
2702 // Caster not in world, might be spell triggered from aura removal
2703 if (!m_caster->IsInWorld())
2704 return;
2705
2706 // Remove old farsight if exist
2707 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2708
2709 DynamicObject* dynObj = new DynamicObject(true);
2710 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2711 {
2712 delete dynObj;
2713 return;
2714 }
2715
2716 dynObj->SetDuration(duration);
2717 dynObj->SetCasterViewpoint(updateViewerVisibility);
2718}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:203
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:231
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:638

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2763{
2765 return;
2766
2767 if (!unitTarget->IsPlayer())
2768 return;
2769
2770 // not scale value for item based reward (/10 value expected)
2771 if (m_CastItem)
2772 {
2773 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2774 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2776 return;
2777 }
2778
2779 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2780 if (damage <= 50)
2781 {
2783 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2784 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2785 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2786 }
2787 else
2788 {
2789 //maybe we have correct honor_gain in damage already
2790 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2791 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2793 }
2794}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6064

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1305{
1307 return;
1308
1309 if (!m_spellAura || !unitTarget)
1310 return;
1313}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4307{
4309 return;
4310
4312 return;
4313
4314 Player* player = m_caster->ToPlayer();
4315
4316 // glyph sockets level requirement
4317 uint8 minLevel = 0;
4318 switch (m_glyphIndex)
4319 {
4320 case 0:
4321 case 1:
4322 minLevel = 15;
4323 break;
4324 case 2:
4325 minLevel = 50;
4326 break;
4327 case 3:
4328 minLevel = 30;
4329 break;
4330 case 4:
4331 minLevel = 70;
4332 break;
4333 case 5:
4334 minLevel = 80;
4335 break;
4336 }
4337 if (minLevel && m_caster->GetLevel() < minLevel)
4338 {
4340 return;
4341 }
4342
4343 // apply new one
4344 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4345 {
4346 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4347 {
4348 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4349 {
4350 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4351 {
4353 return; // glyph slot mismatch
4354 }
4355 }
4356
4357 // remove old glyph aura
4358 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4359 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4360 {
4361 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4362
4363 // Removed any triggered auras
4364 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4365 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4366 {
4367 Aura* aura = iter->second;
4368 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4369 {
4370 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4371 {
4372 player->RemoveOwnedAura(iter);
4373 continue;
4374 }
4375 }
4376 ++iter;
4377 }
4378
4379 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4380 }
4381
4382 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4384 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4385 player->SendTalentsInfoData(false);
4386 }
4387 }
4388}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:147
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14424
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3019
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1752
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1743
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1744
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4686
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1321
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1028

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6251{
6253 return;
6254
6255 if (!unitTarget)
6256 return;
6257
6258 Player* player = unitTarget->ToPlayer();
6259 if (!player)
6260 {
6261 return;
6262 }
6263
6264 WorldLocation homeLoc;
6265 uint32 areaId = player->GetAreaId();
6266
6267 if (m_spellInfo->Effects[effIndex].MiscValue)
6268 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6269
6270 if (m_targets.HasDst())
6271 homeLoc.WorldRelocate(*destTarget);
6272 else
6273 {
6274 homeLoc = player->GetWorldLocation();
6275 }
6276
6277 player->SetHomebind(homeLoc, areaId);
6278
6279 // binding
6280 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6281 data << float(homeLoc.GetPositionX());
6282 data << float(homeLoc.GetPositionY());
6283 data << float(homeLoc.GetPositionZ());
6284 data << uint32(homeLoc.GetMapId());
6285 data << uint32(areaId);
6286 player->SendDirectMessage(&data);
6287
6288 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6289 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6290 // zone update
6291 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6292 data << m_caster->GetGUID();
6293 data << uint32(areaId);
6294 player->SendDirectMessage(&data);
6295}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:281
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5692
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4898

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4674{
4676 return;
4677
4678 if (m_caster->IsPlayer())
4679 m_caster->ToPlayer()->SetCanBlock(true);
4680}
void SetCanBlock(bool value)
Definition: Player.cpp:13136

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6178{
6180 return;
6181
6182 if (!m_caster->IsPlayer())
6183 return;
6184
6185 Player* p_caster = m_caster->ToPlayer();
6186 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6187 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6188
6189 for (; n_buttons; --n_buttons, ++button_id)
6190 {
6191 ActionButton const* ab = p_caster->GetActionButton(button_id);
6192 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6193 continue;
6194
6197 uint32 spell_id = ab->GetAction();
6198 if (!spell_id)
6199 continue;
6200
6201 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6202 if (!spellInfo)
6203 continue;
6204
6205 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6206 continue;
6207
6209 continue;
6210
6211 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6212 if (m_caster->GetPower(POWER_MANA) < cost)
6213 continue;
6214
6216 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6217 }
6218}
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
Definition: Player.h:253
uint32 GetAction() const
Definition: Player.h:261
ActionButtonType GetType() const
Definition: Player.h:260
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5638
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3859

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4893{
4895 {
4896 if (!unitTarget)
4897 return;
4898
4899 ObjectGuid targetGUID = ObjectGuid::Empty;
4900 Player* player = m_caster->ToPlayer();
4901 if (player)
4902 {
4903 // charge changes fall time
4905
4907 {
4908 targetGUID = unitTarget->GetGUID();
4909 }
4910 }
4911
4912 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4913 // Spell is not using explicit target - no generated path
4914 if (!m_preGeneratedPath)
4915 {
4917 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4918 }
4919 else
4920 {
4921 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4922 }
4923
4924 if (player)
4925 {
4926 sScriptMgr->AnticheatSetUnderACKmount(player);
4927 }
4928 }
4929}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2823
Definition: Position.h:28
float m_positionZ
Definition: Position.h:58
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2318
MotionMaster * GetMotionMaster()
Definition: Unit.h:1615
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:670

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1762{
1764 return;
1765
1766 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1767 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1768}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5142
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1632

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1771{
1773 return;
1774
1775 if (!unitTarget)
1776 return;
1777
1778 Player* player = unitTarget->ToPlayer();
1779 if (!player)
1780 {
1781 return;
1782 }
1783
1784 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1785
1786 if (itemId)
1787 DoCreateItem(effIndex, itemId);
1788
1789 // special case: fake item replaced by generate using spell_loot_template
1791 {
1792 if (itemId)
1793 {
1794 if (!player->HasItemCount(itemId))
1795 return;
1796
1797 // remove reagent
1798 uint32 count = 1;
1799 player->DestroyItemCount(itemId, count, true);
1800
1801 // create some random items
1803 }
1804 else
1805 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1806 }
1808}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13491
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3123
bool IsLootCrafting() const
Definition: SpellInfo.cpp:924

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1811{
1813 return;
1814
1815 if (!unitTarget)
1816 return;
1817
1818 Player* player = unitTarget->ToPlayer();
1819 if (!player)
1820 {
1821 return;
1822 }
1823
1824 // create some random items
1827}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5816{
5818 return;
5819
5821 return;
5822
5823 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5824 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5825 if (!pet)
5826 return;
5827
5828 // add to world
5829 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5830
5831 // unitTarget has pet now
5832 unitTarget->SetMinion(pet, true);
5833
5834 pet->InitTalentForLevel();
5835
5836 if (unitTarget->IsPlayer())
5837 {
5840 }
5841}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2225
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:507
void PetSpellInitialize()
Definition: Player.cpp:9468
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10649
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17316
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:555

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5227{
5229 return;
5230
5231 int32 mana = 0;
5232 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5233 {
5234 if (!m_caster->m_SummonSlot[slot])
5235 continue;
5236
5238 if (totem && totem->IsTotem())
5239 {
5240 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5241 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5242 if (spellInfo)
5243 {
5244 mana += spellInfo->ManaCost;
5246 }
5247 totem->ToTotem()->UnSummon();
5248 }
5249 }
5250 ApplyPct(mana, damage);
5251 if (mana)
5252 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5253}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:1729
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1224
uint32 GetCreateMana() const
Definition: Unit.h:1448
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1797
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3314
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5844{
5846 return;
5847
5848 if (!unitTarget)
5849 return;
5850
5851 Player* player = unitTarget->ToPlayer();
5852 if (!player)
5853 {
5854 return;
5855 }
5856
5857 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5858 if (sTaxiNodesStore.LookupEntry(nodeid))
5859 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5860}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4444{
4446 return;
4447
4449 return;
4450
4451 if (Player* caster = m_caster->ToPlayer())
4452 {
4453 caster->UpdateCraftSkill(m_spellInfo->Id);
4454 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4455 }
4456
4457 // item will be removed at disenchanting end
4458}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:84

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4530{
4532 return;
4533
4534 if (!unitTarget || !unitTarget->IsPet())
4535 return;
4536
4537 Pet* pet = unitTarget->ToPet();
4538
4539 ExecuteLogEffectUnsummonObject(effIndex, pet);
4541}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:884
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5160

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2542{
2544 return;
2545
2546 if (!unitTarget)
2547 return;
2548
2549 // Create dispel mask by dispel type
2550 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2551 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2552
2553 DispelChargesList dispel_list;
2554 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2555 if (dispel_list.empty())
2556 return;
2557
2558 // Ok if exist some buffs for dispel try dispel it
2559 uint32 failCount = 0;
2560 DispelChargesList success_list;
2561 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2562 // dispel N = damage buffs (or while exist buffs for dispel)
2563 for (int32 count = 0; count < damage && !dispel_list.empty();)
2564 {
2565 // Random select buff for dispel
2566 DispelChargesList::iterator itr = dispel_list.begin();
2567 std::advance(itr, urand(0, dispel_list.size() - 1));
2568
2569 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2570 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2571 if (!chance)
2572 {
2573 dispel_list.erase(itr);
2574 continue;
2575 }
2576 else
2577 {
2578 if (roll_chance_i(chance))
2579 {
2580 bool alreadyListed = false;
2581 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2582 {
2583 if (successItr->first->GetId() == itr->first->GetId())
2584 {
2585 ++successItr->second;
2586 alreadyListed = true;
2587 }
2588 }
2589 if (!alreadyListed)
2590 success_list.push_back(std::make_pair(itr->first, 1));
2591 --itr->second;
2592 if (itr->second <= 0)
2593 dispel_list.erase(itr);
2594 }
2595 else
2596 {
2597 if (!failCount)
2598 {
2599 // Failed to dispell
2600 dataFail << m_caster->GetGUID(); // Caster GUID
2601 dataFail << unitTarget->GetGUID(); // Victim GUID
2602 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2603 }
2604 ++failCount;
2605 dataFail << uint32(itr->first->GetId()); // Spell Id
2606 }
2607 ++count;
2608 }
2609 }
2610
2611 if (failCount)
2612 m_caster->SendMessageToSet(&dataFail, true);
2613
2614 // put in combat
2617
2618 if (success_list.empty())
2619 return;
2620
2621 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2622 // Send packet header
2623 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2624 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2625 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2626 dataSuccess << uint8(0); // not used
2627 dataSuccess << uint32(success_list.size()); // count
2628 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2629 {
2630 // Send dispelled spell info
2631 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2632 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2633 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2634 }
2635 m_caster->SendMessageToSet(&dataSuccess, true);
2636
2637 // On success dispel
2638 // Devour Magic
2640 {
2641 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2642 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2643 // Glyph of Felhunter
2644 if (Unit* owner = m_caster->GetOwner())
2645 if (owner->GetAura(56249))
2646 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2647 }
2648}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition: Unit.cpp:5583
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:4923
uint32 GetCategory() const
Definition: SpellInfo.cpp:870

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5132{
5134 return;
5135
5136 if (!unitTarget)
5137 return;
5138
5139 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5140
5141 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5142
5143 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5144 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5145 {
5146 Aura* aura = itr->second;
5148 continue;
5150 {
5151 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5152 {
5153 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5154
5155 // spell only removes 1 bleed effect do not continue
5156 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5157 {
5158 break;
5159 }
5160 }
5161 }
5162 }
5163
5164 for (; dispel_list.size(); dispel_list.pop())
5165 {
5166 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5167 }
5168
5169 // put in combat
5172}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4757
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2665{
2667 return;
2668
2669 // Check for possible target
2670 if (!unitTarget || unitTarget->IsEngaged())
2671 return;
2672
2673 // target must be OK to do this
2675 return;
2676
2679}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20502
bool IsEngaged() const
Definition: Unit.h:817
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition: MotionMaster.cpp:798

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2651{
2653 return;
2654
2656}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:769

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4081{
4083 return;
4084
4085 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4086 return;
4087
4088 Player* caster = m_caster->ToPlayer();
4089 Player* target = unitTarget->ToPlayer();
4090
4091 // caster or target already have requested duel
4092 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4093 return;
4094
4095 // Players can only fight a duel in zones with this flag
4096 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4097 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4098 {
4099 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4100 return;
4101 }
4102
4103 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4104 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4105 {
4106 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4107 return;
4108 }
4109
4110 //CREATE DUEL FLAG OBJECT
4111 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4112 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4113
4114 Map* map = m_caster->GetMap();
4115 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4116 map, m_caster->GetPhaseMask(),
4120 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4121 {
4122 delete pGameObj;
4123 return;
4124 }
4125
4128 int32 duration = m_spellInfo->GetDuration();
4129 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4130 pGameObj->SetSpellId(m_spellInfo->Id);
4131
4132 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4133
4134 m_caster->AddGameObject(pGameObj);
4135 map->AddToMap(pGameObj, true);
4136 //END
4137
4138 // Send request
4139 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4140 data << pGameObj->GetGUID();
4141 data << caster->GetGUID();
4142 caster->GetSession()->SendPacket(&data);
4143 target->GetSession()->SendPacket(&data);
4144
4145 // create duel-info
4146 bool isMounted = (GetSpellInfo()->Id == 62875);
4147 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4148 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4149
4150 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4151 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4152
4153 sScriptMgr->OnPlayerDuelRequest(target, caster);
4154}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1303
void SetSpellId(uint32 id)
Definition: GameObject.h:177
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:446
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1141
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:755
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6157
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5154
uint32 flags
Definition: DBCStructure.h:523

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
664{
666 return;
667
669 return;
670
671 // selection by spell family
673 {
675 {
676 switch (m_spellInfo->Id)
677 {
678 // Trial of the Champion, Trample
679 case 67866:
680 {
682 unitTarget->CastSpell(unitTarget, 67867, false);
683 return;
684 }
685 // Trial of the Champion, Hammer of the Righteous
686 case 66867:
687 {
688 if (!unitTarget)
689 return;
690 if (unitTarget->HasAura(66940))
691 m_caster->CastSpell(unitTarget, 66903, true);
692 else
693 m_caster->CastSpell(unitTarget, 66904, true);
694 return;
695 }
696 case 17731:
697 case 69294:
698 {
700 return;
701
705 trigger->CastSpell(trigger, 17731, false);
706
707 return;
708 }
709 // HoL, Arc Weld
710 case 59086:
711 {
713 m_caster->CastSpell(m_caster, 59097, true);
714
715 return;
716 }
717 }
718 break;
719 }
721 switch (m_spellInfo->Id)
722 {
723 case 31789: // Righteous Defense (step 1)
724 {
725 if (!unitTarget)
726 return;
727 // not empty (checked), copy
729
730 // remove invalid attackers
731 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
732 if (!(*aItr)->IsValidAttackTarget(m_caster))
733 aItr = attackers.erase(aItr);
734 else
735 ++aItr;
736
737 // selected from list 3
738 uint32 maxTargets = std::min<uint32>(3, attackers.size());
739 for (uint32 i = 0; i < maxTargets; ++i)
740 {
741 Unit::AttackerSet::iterator aItr = attackers.begin();
742 std::advance(aItr, urand(0, attackers.size() - 1));
743 m_caster->CastSpell((*aItr), 31790, true);
744 attackers.erase(aItr);
745 }
746
747 return;
748 }
749 }
750 break;
752 // Hunger for Blood
753 if (m_spellInfo->Id == 51662)
754 {
755 m_caster->CastSpell(m_caster, 63848, true);
756 return;
757 }
758 break;
759 }
760
761 // pet auras
762 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
763 {
764 m_caster->AddPetAura(petSpell);
765 return;
766 }
767
768 // normal DB scripted effect
769 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
771
772 if (gameObjTarget)
773 {
774 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
775 }
776 else if (unitTarget && unitTarget->IsCreature())
777 {
778 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
779 }
780 else if (itemTarget)
781 {
782 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
783 }
784}
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:57
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:47
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
uint8 GetGoAnimProgress() const
Definition: GameObject.h:210
time_t GetRespawnTime() const
Definition: GameObject.h:184
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2355
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17262
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:632
AttackerSet const & getAttackers() const
Definition: Unit.h:786
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:33
Definition: SpellMgr.h:470

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5256{
5258 return;
5259
5260 if (!unitTarget)
5261 return;
5262
5263 Player* player = unitTarget->ToPlayer();
5264 if (!player)
5265 {
5266 return;
5267 }
5268
5269 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5270
5271 // -1 means all player equipped items and -2 all items
5272 if (slot < 0)
5273 {
5274 player->DurabilityPointsLossAll(damage, (slot < -1));
5276 return;
5277 }
5278
5279 // invalid slot value
5280 if (slot >= INVENTORY_SLOT_BAG_END)
5281 return;
5282
5283 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5284 {
5285 player->DurabilityPointsLoss(item, damage);
5286 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5287 }
5288}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:443
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4746
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4772
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5128

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5291{
5293 return;
5294
5295 if (!unitTarget)
5296 return;
5297
5298 Player* player = unitTarget->ToPlayer();
5299 if (!player)
5300 {
5301 return;
5302 }
5303
5304 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5305
5306 // FIXME: some spells effects have value -1/-2
5307 // Possibly its mean -1 all player equipped items and -2 all items
5308 if (slot < 0)
5309 {
5310 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5311 return;
5312 }
5313
5314 // invalid slot value
5315 if (slot >= INVENTORY_SLOT_BAG_END)
5316 return;
5317
5318 if (damage <= 0)
5319 return;
5320
5321 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5322 player->DurabilityLoss(item, float(damage) / 100.0f);
5323}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4702
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4728

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4391{
4393 return;
4394
4395 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4396 if (!unitTarget)
4397 return;
4398
4399 Player* item_owner = unitTarget->ToPlayer();
4400 if (!item_owner)
4401 {
4402 return;
4403 }
4404
4406 if (!item)
4407 return;
4408
4409 // must be equipped
4410 if (!item->IsEquipped())
4411 return;
4412
4413 if (m_spellInfo->Effects[effIndex].MiscValue)
4414 {
4415 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4416 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4417 if (!duration)
4418 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4419 if (!duration)
4420 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4421
4422 // Xinef: Venomhide poison, no other spell uses this effect...
4423 if (m_spellInfo->Id == 14792)
4424 duration = 5 * MINUTE * IN_MILLISECONDS;
4425
4426 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4427 if (!pEnchant)
4428 return;
4429
4430 // Always go to temp enchantment slot
4432
4433 // Enchantment will not be applied if a different one already exists
4434 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4435 return;
4436
4437 // Apply the temporary enchantment
4438 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4439 item_owner->ApplyEnchantment(item, slot, true);
4440 }
4441}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
bool IsEquipped() const
Definition: Item.cpp:790
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:921
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4306
uint32 charges
Definition: DBCStructure.h:1842

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2809{
2811 return;
2812
2813 if (!m_caster->IsPlayer())
2814 return;
2815 if (!itemTarget)
2816 return;
2817
2818 Player* p_caster = m_caster->ToPlayer();
2819
2820 // Handle vellums
2822 {
2823 // destroy one vellum from stack
2824 uint32 count = 1;
2825 p_caster->DestroyItemCount(itemTarget, count, true);
2826 unitTarget = p_caster;
2827 // and add a scroll
2828 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2829 itemTarget = nullptr;
2830 m_targets.SetItemTarget(nullptr);
2831 }
2832 else
2833 {
2834 // do not increase skill if vellum used
2836 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2837
2838 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2839 if (!enchant_id)
2840 return;
2841
2842 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2843 if (!pEnchant)
2844 return;
2845
2846 // item can be in trade slot and have owner diff. from caster
2847 Player* item_owner = itemTarget->GetOwner();
2848 if (!item_owner)
2849 return;
2850
2851 // remove old enchanting before applying new if equipped
2853
2855
2856 // add new enchanting if equipped
2858
2859 item_owner->RemoveTradeableItem(itemTarget);
2861 }
2862}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1265
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4141
void SetItemTarget(Item *item)
Definition: Spell.cpp:327

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2865{
2867 return;
2868
2869 if (!m_caster->IsPlayer())
2870 return;
2871 if (!itemTarget)
2872 return;
2873
2874 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2875 if (!enchant_id)
2876 return;
2877
2878 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2879 if (!pEnchant)
2880 return;
2881
2882 // support only enchantings with add socket in this slot
2883 {
2884 bool add_socket = false;
2885 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2886 {
2887 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2888 {
2889 add_socket = true;
2890 break;
2891 }
2892 }
2893 if (!add_socket)
2894 {
2895 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2897 return;
2898 }
2899 }
2900
2901 // item can be in trade slot and have owner diff. from caster
2902 Player* item_owner = itemTarget->GetOwner();
2903 if (!item_owner)
2904 return;
2905
2906 // remove old enchanting before applying new if equipped
2908
2910
2911 // add new enchanting if equipped
2913
2914 item_owner->RemoveTradeableItem(itemTarget);
2916}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2919{
2921 return;
2922
2923 if (!m_caster->IsPlayer())
2924 return;
2925
2926 Player* p_caster = m_caster->ToPlayer();
2927
2928 // Rockbiter Weapon apply to both weapon
2929 if (!itemTarget)
2930 return;
2932 {
2933 uint32 spell_id = 0;
2934
2935 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2936 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2937 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2938 switch (damage)
2939 {
2940 // Rank 1
2941 case 2:
2942 spell_id = 36744;
2943 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2944 // Rank 2
2945 case 4:
2946 spell_id = 36753;
2947 break; // 0% [ 7% == 4, 14% == 4]
2948 case 5:
2949 spell_id = 36751;
2950 break; // 20%
2951 // Rank 3
2952 case 6:
2953 spell_id = 36754;
2954 break; // 0% [ 7% == 6, 14% == 6]
2955 case 7:
2956 spell_id = 36755;
2957 break; // 20%
2958 // Rank 4
2959 case 9:
2960 spell_id = 36761;
2961 break; // 0% [ 7% == 6]
2962 case 10:
2963 spell_id = 36758;
2964 break; // 14%
2965 case 11:
2966 spell_id = 36760;
2967 break; // 20%
2968 default:
2969 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2970 return;
2971 }
2972
2973 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2974 if (!spellInfo)
2975 {
2976 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
2977 return;
2978 }
2979
2980 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
2981 {
2982 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
2983 {
2984 if (item->IsFitToSpellRequirements(m_spellInfo))
2985 {
2986 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
2987 SpellCastTargets targets;
2988 targets.SetItemTarget(item);
2989 spell->prepare(&targets);
2990 }
2991 }
2992 }
2993 return;
2994 }
2995 if (!itemTarget)
2996 return;
2997
2998 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2999
3000 if (!enchant_id)
3001 {
3002 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3003 return;
3004 }
3005
3006 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3007 if (!pEnchant)
3008 {
3009 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3010 return;
3011 }
3012
3013 // select enchantment duration
3014 uint32 duration;
3015
3016 // rogue family enchantments exception by duration
3017 if (m_spellInfo->Id == 38615)
3018 duration = 1800; // 30 mins
3019 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3021 duration = 3600; // 1 hour
3022 // shaman family enchantments
3024 duration = 1800; // 30 mins
3025 // other cases with this SpellVisual already selected
3026 else if (m_spellInfo->SpellVisual[0] == 215)
3027 duration = 1800; // 30 mins
3028 // some fishing pole bonuses except Glow Worm which lasts full hour
3029 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3030 duration = 600; // 10 mins
3031 // shaman rockbiter enchantments
3032 else if (m_spellInfo->SpellVisual[0] == 0)
3033 duration = 1800; // 30 mins
3034 else if (m_spellInfo->Id == 29702)
3035 duration = 300; // 5 mins
3036 else if (m_spellInfo->Id == 37360)
3037 duration = 300; // 5 mins
3038 // default case
3039 else
3040 duration = 3600; // 1 hour
3041
3042 // item can be in trade slot and have owner diff. from caster
3043 Player* item_owner = itemTarget->GetOwner();
3044 if (!item_owner)
3045 return;
3046
3047 // remove old enchanting before applying new if equipped
3049
3050 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3051
3052 // add new enchanting if equipped
3054
3055 item_owner->RemoveTradeableItem(itemTarget);
3057}
WeaponAttackType
Definition: Unit.h:208
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3539
Definition: Spell.h:109
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3475
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1864{
1866 return;
1867
1868 if (!unitTarget)
1869 return;
1870 if (!unitTarget->IsAlive())
1871 return;
1872
1873 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1874 return;
1875
1876 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1877
1880 return;
1881
1882 if (unitTarget->GetMaxPower(power) == 0)
1883 return;
1884
1885 // Some level depends spells
1886 int level_multiplier = 0;
1887 int level_diff = 0;
1888 switch (m_spellInfo->Id)
1889 {
1890 case 9512: // Restore Energy
1891 level_diff = m_caster->GetLevel() - 40;
1892 level_multiplier = 2;
1893 break;
1894 case 24571: // Blood Fury
1895 level_diff = m_caster->GetLevel() - 60;
1896 level_multiplier = 10;
1897 break;
1898 case 24532: // Burst of Energy
1899 level_diff = m_caster->GetLevel() - 60;
1900 level_multiplier = 4;
1901 break;
1902 case 31930: // Judgements of the Wise
1903 case 63375: // Improved Stormstrike
1904 case 68082: // Glyph of Seal of Command
1906 break;
1907 case 48542: // Revitalize
1909 break;
1910 case 71132: // Glyph of Shadow Word: Pain
1911 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1912 break;
1913 default:
1914 break;
1915 }
1916
1917 if (level_diff > 0)
1918 damage -= level_multiplier * level_diff;
1919
1920 if (damage < 0)
1921 return;
1922
1924
1925 // Mad Alchemist's Potion
1926 if (m_spellInfo->Id == 45051)
1927 {
1928 // find elixirs on target
1929 bool guardianFound = false;
1930 bool battleFound = false;
1932 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1933 {
1934 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1935 if (!guardianFound)
1937 guardianFound = true;
1938 if (!battleFound)
1940 battleFound = true;
1941 if (battleFound && guardianFound)
1942 break;
1943 }
1944
1945 // get all available elixirs by mask and spell level
1946 std::set<uint32> availableElixirs;
1947 if (!guardianFound)
1948 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1949 if (!battleFound)
1950 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1951 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1952 {
1953 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1954 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1955 availableElixirs.erase(itr++);
1956 else
1957 ++itr;
1958 }
1959
1960 if (!availableElixirs.empty())
1961 {
1962 // cast random elixir on target
1964 }
1965 }
1966}
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:337
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:657
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:133
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11235

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1969{
1971 return;
1972
1973 if (!unitTarget)
1974 return;
1975 if (!unitTarget->IsAlive())
1976 return;
1977
1978 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1979 return;
1980
1981 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1982
1984 return;
1985
1986 uint32 maxPower = unitTarget->GetMaxPower(power);
1987 if (maxPower == 0)
1988 return;
1989
1990 uint32 gain = CalculatePct(maxPower, damage);
1992}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
300{
302 return;
303
304 if (!unitTarget || !unitTarget->IsAlive())
305 return;
306
307 if (unitTarget->IsPlayer())
309 else
310 {
312
313 uint32 absorb = dmgInfo.GetAbsorb();
314 uint32 resist = dmgInfo.GetResist();
315 uint32 envDamage = dmgInfo.GetDamage();
316
317 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
318 damage = envDamage;
319
321 }
322}
@ DAMAGE_FIRE
Definition: Player.h:839
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:754

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4497{
4499 return;
4500
4501 Player* player = m_caster->ToPlayer();
4502 if (!player)
4503 return;
4504
4505 Item* foodItem = itemTarget;
4506 if (!foodItem)
4507 return;
4508
4509 Pet* pet = player->GetPet();
4510 if (!pet)
4511 return;
4512
4513 if (!pet->IsAlive())
4514 return;
4515
4516 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4517 if (benefit <= 0)
4518 return;
4519
4520 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4521
4522 uint32 count = 1;
4523 player->DestroyItemCount(foodItem, count, true);
4525
4526 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4527}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5148

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
998{
1000 return;
1001
1002 if (!unitTarget)
1003 return;
1004
1005 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1006
1007 // normal case
1008 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1009
1010 if (!spellInfo)
1011 {
1012 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1013 return;
1014 }
1015
1016 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1017 {
1018 switch (m_spellInfo->Id)
1019 {
1020 case 52588: // Skeletal Gryphon Escape
1021 case 48598: // Ride Flamebringer Cue
1023 break;
1024 case 52463: // Hide In Mine Car
1025 case 52349: // Overtake
1026 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1027 return;
1028 case 72378: // Blood Nova
1029 case 73058: // Blood Nova
1030 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1031 break;
1032 }
1033 }
1034
1035 CustomSpellValues values;
1036 // set basepoints for trigger with value effect
1038 {
1039 // maybe need to set value only when basepoints == 0?
1043 }
1044
1045 SpellCastTargets targets;
1046 targets.SetUnitTarget(m_caster);
1047
1048 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1049}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:114
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:113
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:918
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:919
Definition: SpellDefines.h:162
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:164

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4753{
4755 return;
4756
4757 // xinef: clear focus
4759
4761 data << m_caster->GetGUID();
4762
4764 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4765 Cell::VisitWorldObjects(m_caster, notifier, dist);
4766
4767 // xinef: we should also force pets to remove us from current target
4768 Unit::AttackerSet attackerSet;
4769 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4770 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4771 attackerSet.insert(*itr);
4772
4773 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4774 (*itr)->AttackStop();
4775
4776 // Xinef: Mirror images code Initialize Images
4777 if (m_spellInfo->Id == 58836)
4778 {
4779 std::vector<Unit*> images;
4780 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4781 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4782 images.push_back(*itr);
4783
4784 if (images.empty())
4785 return;
4786
4787 UnitList targets;
4788 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4791 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4792 {
4793 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4794 continue;
4795
4796 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4797 {
4798 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4799 {
4800 SpellInfo const* si = spell->GetSpellInfo();
4801 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4802 {
4803 Creature* c = (*iter)->ToCreature();
4804 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4805 continue;
4806 }
4807
4808 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4809 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4810 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4811 {
4812 // at least one effect truly targets an unit, interrupt the spell
4813 interrupt = true;
4814 break;
4815 }
4816
4817 if (interrupt)
4818 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4819 }
4820 }
4821 }
4822 }
4823}
std::list< Unit * > UnitList
Definition: Unit.h:76
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3161
uint32 rank
Definition: CreatureData.h:207
ControlSet m_Controlled
Definition: Unit.h:1793
void SendClearTarget()
Definition: Unit.cpp:20301
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:206
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:192
Definition: GridNotifiers.h:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5888{
5890 return;
5891
5892 if (!gameObjTarget)
5893 return;
5894
5895 Unit* caster = m_originalCaster;
5896 if (!caster)
5897 return;
5898
5899 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5901 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5902 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5904}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2277
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:10003
Definition: DBCStructure.h:938
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:950

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5918{
5920 return;
5921
5923 return;
5924
5927}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2340

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1458{
1460 return;
1461
1462 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1463 {
1464 // Try to get original caster
1466
1467 // Skip if m_originalCaster not available
1468 if (!caster)
1469 return;
1470
1471 int32 addhealth = damage;
1472
1473 // Vessel of the Naaru (Vial of the Sunwell trinket)
1474 if (m_spellInfo->Id == 45064)
1475 {
1476 // Amount of heal - depends from stacked Holy Energy
1477 int damageAmount = 0;
1478 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1479 {
1480 damageAmount += aurEff->GetAmount();
1482 }
1483
1484 addhealth += damageAmount;
1485 }
1486 // Swiftmend - consumes Regrowth or Rejuvenation
1488 {
1490 // find most short by duration
1491 AuraEffect* forcedTargetAura = nullptr;
1492 AuraEffect* targetAura = nullptr;
1493 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1494 {
1495 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1496 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1497 {
1498 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1499 {
1500 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1501 forcedTargetAura = *i;
1502 }
1503 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1504 targetAura = *i;
1505 }
1506 }
1507
1508 if (forcedTargetAura)
1509 targetAura = forcedTargetAura;
1510
1511 if (!targetAura)
1512 {
1513 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1514 return;
1515 }
1516
1517 int32 tickheal = targetAura->GetAmount();
1518 if (Unit* auraCaster = targetAura->GetCaster())
1519 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1520
1521 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1522 //It is said that talent bonus should not be included
1523
1524 int32 tickcount = 0;
1525 // Rejuvenation
1526 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1527 tickcount = 4;
1528 // Regrowth
1529 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1530 tickcount = 6;
1531
1532 addhealth += tickheal * tickcount;
1533
1534 // Glyph of Swiftmend
1535 if (!caster->HasAura(54824))
1536 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1537
1538 //addhealth += tickheal * tickcount;
1539 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1540 }
1541 // Death Pact - return pct of max health to caster
1543 {
1544 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1545 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1546 }
1547 else if (m_spellInfo->Id != 33778) // not lifebloom
1548 {
1549 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1550 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1551 }
1552
1553 // Implemented this way as there is no other way to do it currently (that I know :P)...
1554 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1555 {
1557 {
1558 m_damage = 0;
1559 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1560 return;
1561 }
1562 }
1563
1564 m_damage -= addhealth;
1565 }
1566}
@ DOT
Definition: Unit.h:250
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1307
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:298
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:878
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:64
uint32 TargetAuraState
Definition: SpellInfo.h:340

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3660{
3662 return;
3663
3664 if (!unitTarget || !unitTarget->IsAlive())
3665 return;
3666
3667 int32 addhealth = 0;
3668
3669 // damage == 0 - heal for caster max health
3670 if (damage == 0)
3671 addhealth = m_caster->GetMaxHealth();
3672 else
3673 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3674
3675 m_healing += addhealth;
3676}
uint32 GetMaxHealth() const
Definition: Unit.h:870

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), Unit::IsAlive(), m_caster, m_healing, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1604{
1606 return;
1607
1608 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1609 return;
1610
1613
1614 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1615
1616 // xinef: handled in spell.cpp
1617 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1618
1619 m_damage += damage;
1620 // get max possible damage, don't count overkill for heal
1621 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1622
1623 //if (m_caster->IsAlive())
1624 //{
1625 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1626 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1627
1628 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1629 //}
1630}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11755
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11579

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4461{
4463 return;
4464
4465 if (!unitTarget)
4466 return;
4467
4468 Player* player = unitTarget->ToPlayer();
4469 if (!player)
4470 {
4471 return;
4472 }
4473
4474 uint8 currentDrunk = player->GetDrunkValue();
4475 int32 drunkMod = damage;
4476
4477 if (drunkMod == 0)
4478 return;
4479
4480 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4481 // In addition, we would not want currentDrunk to become more than 100.
4482 // So before adding the values, let's check that everything is fine.
4483 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4484 currentDrunk = 100;
4485 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4486 currentDrunk = 0;
4487 else
4488 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4489
4490 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4491
4492 if (currentDrunk == 100 && roll_chance_i(25))
4493 player->CastSpell(player, 67468, false); // Drunken Vomit
4494}
uint8 GetDrunkValue() const
Definition: Player.h:2153
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:971

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
276{
278 return;
279
280 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
281 return;
282
283 if (unitTarget->IsPlayer())
285 return;
286
287 if (m_caster == unitTarget) // prevent interrupt message
288 finish();
289
290 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
291 data << m_caster->GetGUID();
292 data << unitTarget->GetGUID();
293 data << uint32(m_spellInfo->Id);
294 m_caster->SendMessageToSet(&data, true);
295
297}
@ CHEAT_GOD
Definition: Player.h:999
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:810

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3679{
3681 return;
3682
3683 if (!unitTarget || !unitTarget->IsAlive())
3684 return;
3685
3687 // also exist case: apply cooldown to interrupted cast only and to all spells
3688 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3690 {
3692 {
3693 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3694 // check if we can interrupt spell
3695 if ((spell->getState() == SPELL_STATE_CASTING
3696 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3700 {
3701 if (m_originalCaster)
3702 {
3704 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3705 }
3706 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3708 }
3709 }
3710 }
3711}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:29
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4043
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14820
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1455
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5121
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1071{
1073 return;
1074
1075 if (m_caster->IsInFlight())
1076 return;
1077
1078 if (!unitTarget)
1079 return;
1080
1081 float speedXY, speedZ;
1082 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1083 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1084
1085 if (m_caster->IsPlayer())
1086 {
1087 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1088 }
1089}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:227
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1154

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1092{
1094 return;
1095
1096 if (m_caster->IsInFlight())
1097 return;
1098
1099 if (!m_targets.HasDst() || m_caster->GetVehicle())
1100 return;
1101
1102 // Init dest coordinates
1103 float x, y, z;
1104 destTarget->GetPosition(x, y, z);
1105 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1106 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1107 return;
1108
1109 float speedXY, speedZ;
1110 float dist = m_caster->GetExactDist2d(x, y);
1111 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1112
1113 // Override, calculations are incorrect
1114 if (m_spellInfo->Id == 49376) // feral charge
1115 {
1116 speedXY = pow(speedZ * 10, 8);
1118
1119 if (Player* player = m_caster->ToPlayer())
1120 {
1121 player->SetCanTeleport(true);
1122 }
1123
1124 if (m_caster->IsPlayer())
1125 {
1126 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1127 }
1128
1129 return;
1130 }
1131
1132 if (m_spellInfo->Id == 57604) // death grip
1133 {
1134 speedZ = 3.0f;
1135 speedXY = 50.0f;
1136 }
1137
1138 // crash fix?
1139 if (speedXY < 1.0f)
1140 speedXY = 1.0f;
1141
1142 if (Player* player = m_caster->ToPlayer())
1143 {
1144 player->SetCanTeleport(true);
1145 }
1146 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1147
1148 if (m_caster->IsPlayer())
1149 {
1150 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1151 }
1152}
#define INVALID_HEIGHT
Definition: Map.h:165
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5680{
5682 return;
5683
5684 if (!unitTarget)
5685 return;
5686
5688 if (!player)
5689 {
5690 return;
5691 }
5692
5693 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5694 if (!creatureEntry)
5695 {
5696 if (m_spellInfo->Id == 42793) // Burn Body
5697 creatureEntry = 24008; // Fallen Combatant
5698 }
5699
5700 if (creatureEntry)
5701 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5702}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12736

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5666{
5668 return;
5669
5670 if (!unitTarget)
5671 return;
5672
5674 {
5675 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5676 }
5677}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4957{
4959 return;
4960
4961 if (!unitTarget)
4962 return;
4963
4964 // Xinef: allow entry specific spells to skip those checks
4965 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4966 {
4968 return;
4969
4970 if (unitTarget->GetVehicle())
4971 return;
4972
4973 if (Creature* creatureTarget = unitTarget->ToCreature())
4974 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4975 return;
4976 }
4977
4978 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4980 return;
4981
4982 // Instantly interrupt non melee spells being casted
4985
4986 float ratio = 0.1f;
4987 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
4988 float speedz = float(damage) * ratio;
4989 if (speedxy <= 0.1f && speedz <= 0.1f)
4990 return;
4991
4992 float x, y;
4993 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
4994 {
4995 if (m_targets.HasDst())
4996 destTarget->GetPosition(x, y);
4997 else
4998 return;
4999 }
5000 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5001 {
5002 m_caster->GetPosition(x, y);
5003 }
5004
5005 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5006
5007 if (unitTarget->IsPlayer())
5008 {
5009 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5010 }
5011}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4110
uint32 GetCreatureType() const
Definition: Unit.cpp:15146
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19108

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4683{
4685 return;
4686
4687 if (!unitTarget || unitTarget->IsInFlight())
4688 return;
4689
4690 if (!m_targets.HasDst())
4691 return;
4692
4693 Position dstpos = destTarget->GetPosition();
4695}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19956

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5014{
5016 return;
5017
5018 if (!unitTarget)
5019 return;
5020
5021 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5022 float speedz = damage / 10.0f;
5023 //1891: Disengage
5025
5026 if (m_caster->IsPlayer())
5027 {
5028 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5029 }
5030
5031 // xinef: changes fall time
5032 if (m_caster->IsPlayer())
5034}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19489

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3230{
3232 return;
3233
3234 if (!unitTarget)
3235 return;
3236
3237 if (unitTarget->ToPlayer())
3238 {
3239 EffectLearnSpell(effIndex);
3240 return;
3241 }
3242 Pet* pet = unitTarget->ToPet();
3243 if (!pet)
3244 return;
3245
3246 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3247 if (!learn_spellproto)
3248 return;
3249
3250 pet->learnSpell(learn_spellproto->Id);
3252 pet->GetOwner()->PetSpellInitialize();
3253}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1912
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2516

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2747{
2749 return;
2750
2751 if (!unitTarget->IsPlayer())
2752 return;
2753
2754 if (damage < 0)
2755 return;
2756
2757 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2758 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2759 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2760}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5502
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5316

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2517{
2519 return;
2520
2521 if (!unitTarget)
2522 return;
2523
2524 if (!unitTarget->IsPlayer())
2525 {
2526 if (unitTarget->ToPet())
2527 EffectLearnPetSpell(effIndex);
2528 return;
2529 }
2530
2531 Player* player = unitTarget->ToPlayer();
2532
2533 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2534 player->learnSpell(spellToLearn);
2535
2536 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2537 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2538}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3271
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3229

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5493{
5495 return;
5496
5497 if (!m_caster->IsPlayer())
5498 return;
5499
5500 Player* p_caster = m_caster->ToPlayer();
5502 return;
5503
5504 if (itemTarget->GetCount() < 5)
5505 return;
5506
5507 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5508 {
5509 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5510 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5511 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5512 }
5513
5515}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:92
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7773
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:719

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5326{
5328 return;
5329
5330 if (!unitTarget)
5331 return;
5332
5334}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:839

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
240{
241 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
242}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2061{
2063 return;
2064
2065 if (!m_caster->IsPlayer())
2066 {
2067 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2068 return;
2069 }
2070
2071 Player* player = m_caster->ToPlayer();
2072
2073 uint32 lockId = 0;
2074 ObjectGuid guid;
2075
2076 // Get lockId
2077 if (gameObjTarget)
2078 {
2079 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2080 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2081 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2082 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2083 {
2084 //CanUseBattlegroundObject() already called in CheckCast()
2085 // in battleground check
2086 if (Battleground* bg = player->GetBattleground())
2087 {
2088 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2089 return;
2090 }
2091 }
2092 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2093 {
2094 //CanUseBattlegroundObject() already called in CheckCast()
2095 // in battleground check
2096 if (Battleground* bg = player->GetBattleground())
2097 {
2098 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2099 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2100 return;
2101 }
2102 }
2103 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2104 {
2107 {
2109 }
2110 return;
2111 }
2113 // handle outdoor pvp object opening, return true if go was registered for handling
2114 // these objects must have been spawned by outdoorpvp!
2115 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2116 return;
2117 lockId = goInfo->GetLockId();
2118 guid = gameObjTarget->GetGUID();
2119 }
2120 else if (itemTarget)
2121 {
2122 lockId = itemTarget->GetTemplate()->LockID;
2123 guid = itemTarget->GetGUID();
2124 }
2125 else
2126 {
2127 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2128 return;
2129 }
2130
2131 SkillType skillId = SKILL_NONE;
2132 int32 reqSkillValue = 0;
2133 int32 skillValue;
2134
2135 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2136 if (res != SPELL_CAST_OK)
2137 {
2138 SendCastResult(res);
2139 return;
2140 }
2141
2142 if (gameObjTarget)
2143 SendLoot(guid, LOOT_SKINNING);
2144 else if (itemTarget)
2145 {
2147 if (Player* itemOwner = itemTarget->GetOwner())
2148 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2149 }
2150
2151 // not allow use skill grow at item base open
2152 if (!m_CastItem && skillId != SKILL_NONE)
2153 {
2154 // update skill if really known
2155 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2156 {
2157 if (gameObjTarget)
2158 {
2159 // Allow one skill-up until respawned
2160 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2161 {
2163 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2164 }
2165
2166 }
2167 else if (itemTarget)
2168 {
2169 // Do one skill-up
2170 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2171 }
2172 }
2173 }
2175}
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:103
@ LOOT_SKINNING
Definition: LootMgr.h:86
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:114
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ ITEM_CHANGED
Definition: Item.h:210
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
Unit * GetOwner() const
Definition: GameObject.cpp:1238
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3068
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3074
LootState getLootState() const
Definition: GameObject.h:225
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2442
Definition: GameObjectData.h:31
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:510
uint32 noDamageImmune
Definition: GameObjectData.h:48
struct GameObjectTemplate::@227::@230 button
uint32 losOK
Definition: GameObjectData.h:64
struct GameObjectTemplate::@227::@238 goober
uint32 GetLockId() const
Definition: GameObjectData.h:427
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:715
Definition: Object.h:100
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5136
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:1994

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4665{
4667 return;
4668
4669 if (m_caster->IsPlayer())
4670 m_caster->ToPlayer()->SetCanParry(true);
4671}
void SetCanParry(bool value)
Definition: Player.cpp:13127

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1830{
1832 return;
1833
1834 if (!m_spellAura)
1835 {
1837 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1838
1839 // Caster not in world, might be spell triggered from aura removal
1840 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1841 return;
1842 DynamicObject* dynObj = new DynamicObject(false);
1843 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1844 {
1845 delete dynObj;
1846 return;
1847 }
1848
1850 {
1851 m_spellAura = aura;
1854 }
1855 else
1856 return;
1857 }
1858
1861}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1637
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6079{
6081 return;
6082
6083 if (!unitTarget)
6084 return;
6085
6086 Player* player = unitTarget->ToPlayer();
6087 if (!player)
6088 {
6089 return;
6090 }
6091
6092 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6093
6094 if (!sSoundEntriesStore.LookupEntry(soundid))
6095 {
6096 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6097 return;
6098 }
6099
6101}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6132{
6134 return;
6135
6136 if (!unitTarget)
6137 return;
6138
6139 Player* player = unitTarget->ToPlayer();
6140 if (!player)
6141 {
6142 return;
6143 }
6144
6145 switch (m_spellInfo->Id)
6146 {
6147 case 58730: // Restricted Flight Area
6148 case 58600: // Restricted Flight Area
6150 break;
6151 default:
6152 break;
6153 }
6154
6155 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6156
6157 if (!sSoundEntriesStore.LookupEntry(soundId))
6158 {
6159 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6160 return;
6161 }
6162
6163 player->PlayDirectSound(soundId, player);
6164}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:38
void SendNotification(std::string_view str)
Definition: Chat.cpp:104
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2892

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1416{
1418 return;
1419
1420 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1421 return;
1422
1423 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1424
1426 return;
1427
1428 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1429 if (m_spellInfo->Id == 8129)
1430 {
1433 damage = std::min(damage, maxDamage);
1434
1435 // Remove fear
1437 }
1438
1439 int32 power = damage;
1440 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1441 if (PowerType == POWER_MANA)
1442 power -= unitTarget->GetSpellCritDamageReduction(power);
1443
1444 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1445
1446 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1447 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1448
1449 // add log data before multiplication (need power amount, not damage)
1450 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1451
1452 newDamage = int32(newDamage * dmgMultiplier);
1453
1454 m_damage += newDamage;
1455}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14113
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1034
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5105

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1337{
1339 return;
1340
1341 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1342 return;
1343
1344 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1345
1347 return;
1348
1349 // add spell damage bonus
1352
1353 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1354 int32 power = damage;
1355 if (PowerType == POWER_MANA)
1356 power -= unitTarget->GetSpellCritDamageReduction(power);
1357
1358 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1359
1360 float gainMultiplier = 0.0f;
1361
1362 // Don`t restore from self drain
1363 if (m_caster != unitTarget)
1364 {
1365 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1366
1367 int32 gain = int32(newDamage * gainMultiplier);
1368
1370 }
1371 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1372}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2287{
2289 return;
2290
2291 if (!m_caster->IsPlayer())
2292 return;
2293 Player* p_target = m_caster->ToPlayer();
2294
2296 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2297 {
2298 p_target->AddWeaponProficiency(subClassMask);
2300 }
2301 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2302 {
2303 p_target->AddArmorProficiency(subClassMask);
2305 }
2306}
uint32 GetArmorProficiency() const
Definition: Player.h:1355
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10101
uint32 GetWeaponProficiency() const
Definition: Player.h:1354
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1353
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1352
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2659{
2661 EffectNULL(effIndex);
2662}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:239

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5099{
5101 return;
5102
5103 if (!unitTarget)
5104 return;
5105
5106 Position pos;
5107 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5108 {
5109 if (m_targets.HasDst())
5110 pos.Relocate(*destTarget);
5111 else
5112 return;
5113 }
5114 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5115 {
5116 // Xinef: Increase Z position a little bit, should protect from falling through textures
5118 }
5119
5120 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5121 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5122
5123 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5124
5125 if (unitTarget->IsPlayer())
5126 {
5127 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5128 }
5129}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
double gravity
Definition: MovementUtil.cpp:24
void Relocate(float x, float y)
Definition: Position.h:73

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5037{
5039 return;
5040
5041 if (!unitTarget)
5042 return;
5043
5044 Player* player = unitTarget->ToPlayer();
5045 if (!player)
5046 {
5047 return;
5048 }
5049
5050 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5051
5052 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5053
5054 if (!quest)
5055 return;
5056
5057 // Player has never done this quest
5058 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5059 return;
5060
5061 // remove all quest entries for 'entry' from quest log
5062 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5063 {
5064 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5065 if (logQuest == quest_id)
5066 {
5067 player->SetQuestSlot(slot, 0);
5068
5069 // we ignore unequippable quest items in this case, it's still be equipped
5070 player->TakeQuestSourceItem(logQuest, false);
5071
5072 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5073 {
5074 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5075 player->UpdatePvPState();
5076 }
5077 }
5078 }
5079
5080 player->RemoveRewardedQuest(quest_id);
5081 player->RemoveActiveQuest(quest_id, false);
5082}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:360
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2489
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1390
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1476
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1480
PvPInfo pvpInfo
Definition: Player.h:1829
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1357
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1489
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1424
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1507
Definition: QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:221

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4724{
4726 return;
4727
4728 if (!unitTarget)
4729 return;
4730
4731 Player* player = unitTarget->ToPlayer();
4732 if (!player)
4733 {
4734 return;
4735 }
4736
4737 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4738 if (questId)
4739 {
4740 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4741 if (!quest)
4742 return;
4743
4744 uint16 logSlot = player->FindQuestSlot(questId);
4745 if (logSlot < MAX_QUEST_LOG_SIZE)
4746 player->AreaExploredOrEventHappens(questId);
4747 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4748 player->CompleteQuest(questId); // quest not in log - for internal use
4749 }
4750}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1776
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:597
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1785

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), Player::CompleteQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5705{
5707 return;
5708
5709 if (!unitTarget)
5710 return;
5711
5712 if (Player* player = unitTarget->ToPlayer())
5713 {
5714 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5715 }
5716}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5719{
5721 return;
5722
5723 if (!unitTarget)
5724 return;
5725
5726 Player* player = unitTarget->ToPlayer();
5727 if (!player)
5728 return;
5729
5730 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5731 {
5732 if (!player->CanTakeQuest(quest, false))
5733 return;
5734
5735 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5736 player->AddQuestAndCheckCompletion(quest, player);
5737
5738 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5739 }
5740}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2221

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6221{
6223 return;
6224
6225 if (!unitTarget || !unitTarget->IsPlayer())
6226 return;
6227
6228 Player* player = m_caster->ToPlayer();
6229
6230 if (!player)
6231 return;
6232
6233 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6234
6235 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6236 if (!pProto)
6237 {
6238 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6239 return;
6240 }
6241
6242 if (Item* pItem = player->GetItemByEntry(item_id))
6243 {
6244 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6245 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6246 pItem->SetState(ITEM_CHANGED, player);
6247 }
6248}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5879{
5881 return;
5882
5883 if (unitTarget)
5885}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:846

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6167{
6169 return;
6170
6171 if (!unitTarget)
6172 return;
6173 // there may be need of specifying casterguid of removed auras
6174 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6175}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6067{
6069 return;
6070
6071 if (!unitTarget || !unitTarget->IsCreature() ||
6073 return;
6074
6076}
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4698{
4700 return;
4701
4702 if (!unitTarget)
4703 return;
4704
4705 Player* player = unitTarget->ToPlayer();
4706 if (!player)
4707 {
4708 return;
4709 }
4710
4711 float repChange = static_cast<float>(damage);
4712
4713 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4714
4715 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4716 if (!factionEntry)
4717 return;
4718
4719 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4720 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4721}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5869
ReputationMgr & GetReputationMgr()
Definition: Player.h:2107
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:906

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4616{
4618 return;
4619
4620 if (!unitTarget)
4621 return;
4622
4623 if (!unitTarget)
4624 return;
4625
4626 Player* target = unitTarget->ToPlayer();
4627 if (!target)
4628 {
4629 return;
4630 }
4631
4632 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4633 return;
4634
4635 if (target->isResurrectRequested()) // already have one active request
4636 return;
4637
4638 uint32 health = target->CountPctFromMaxHealth(damage);
4640
4641 ExecuteLogEffectResurrect(effIndex, target);
4642
4644 SendResurrectRequest(target);
4645}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1798
bool isResurrectRequested() const
Definition: Player.h:1810
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5166
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5228

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5175{
5177 return;
5178
5179 if (damage < 0)
5180 return;
5181
5182 Player* player = m_caster->ToPlayer();
5183 if (!player)
5184 {
5185 return;
5186 }
5187
5188 Pet* pet = player->GetPet();
5189 if (!pet)
5190 {
5191 // Position passed to SummonPet is irrelevant with current implementation,
5192 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5193 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5194 return;
5195 }
5196
5198 if (pet->IsAlive())
5199 {
5200 return;
5201 }
5202
5203 // Reposition the pet's corpse before reviving so as not to grab aggro
5204 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5205 float x, y, z; // Will be used later to reposition the pet if we have one
5206 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5207 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5208 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5211 pet->setDeathState(DeathState::Alive);
5212 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5214 pet->SetDisplayId(pet->GetNativeDisplayId());
5215
5216 // xinef: restore movement
5217 if (auto ci = pet->GetCharmInfo())
5218 {
5219 ci->SetIsAtStay(false);
5220 ci->SetIsFollowing(false);
5221 }
5222
5224}
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2699
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:631
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2421
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8929
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:700
void SetHealth(uint32 val)
Definition: Unit.cpp:15442
uint32 GetNativeDisplayId() const
Definition: Unit.h:1523
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:684

References Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4000{
4002 return;
4003
4004 if (!unitTarget)
4005 return;
4006
4008 {
4010 // Xinef: replaced with CombatStop(false)
4013
4014 // Night Elf: Shadowmeld only resets threat temporarily
4015 if (m_spellInfo->Id != 59646)
4017
4018 if (unitTarget->IsPlayer())
4019 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4020 }
4021 else
4022 {
4023 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4024 unitTarget->CombatStop(true);
4025 }
4026
4027 UnitList targets;
4028 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4031 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4032 {
4033 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4034 continue;
4035
4037 {
4038 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4039 {
4040 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4041 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4042 {
4043 Creature* c = (*iter)->ToCreature();
4044 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4045 continue;
4046 }
4047 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4048 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4049 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4050 {
4051 // at least one effect truly targets an unit, interrupt the spell
4052 interrupt = true;
4053 break;
4054 }
4055 if (interrupt)
4056 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4057 }
4058 }
4059 }
4060
4061 // Xinef: Set last sanctuary time
4063}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10405
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition: Unit.cpp:10453
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10372
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:122

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
325{
327 return;
328
329 if (unitTarget && unitTarget->IsAlive())
330 {
331 bool apply_direct_bonus = true;
333 {
335 {
336 // Meteor like spells (divided damage to targets)
338 {
339 uint32 count = 0;
340 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
341 if (ihit->effectMask & (1 << effIndex))
342 ++count;
343
344 damage /= count; // divide to all targets
345 }
346 break;
347 }
349 {
350 // Shield Slam
351 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
352 {
353 uint8 level = m_caster->GetLevel();
354 // xinef: shield block should increase the limit
355 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
356 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
357
358 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
359 }
360 // Victory Rush
361 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
363 // Shockwave
364 else if (m_spellInfo->Id == 46968)
365 {
367 if (pct > 0)
369 break;
370 }
371 break;
372 }
374 {
375 // Incinerate Rank 1 & 2
376 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
377 {
378 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
379 // Check aura state for speed but aura state set not only for Immolate spell
381 {
383 damage += damage / 4;
384 }
385 }
386 // Conflagrate - consumes Immolate or Shadowflame
388 {
389 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
390
392 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
393 {
394 // for caster applied auras only
395 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
396 (*i)->GetCasterGUID() != m_caster->GetGUID())
397 continue;
398
399 // Immolate
400 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
401 {
402 aura = *i; // it selected always if exist
403 break;
404 }
405
406 // Shadowflame
407 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
408 aura = *i; // remember but wait possible Immolate as primary priority
409 }
410
411 // found Immolate or Shadowflame
412 if (aura)
413 {
414 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
415 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
416 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
417 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
418
419 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
420
421 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
422 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
423
424 apply_direct_bonus = false;
425 // Glyph of Conflagrate
426 if (!m_caster->HasAura(56235))
428
429 break;
430 }
431 }
432 // Shadow Bite
433 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
434 {
435 if (m_caster->IsCreature() && m_caster->IsPet())
436 {
437 if (Player* owner = m_caster->GetOwner()->ToPlayer())
438 {
439 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
440 {
441 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
442 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
443 }
444 }
445 }
446 }
447 break;
448 }
450 {
451 // Improved Mind Blast (Mind Blast in shadow form bonus)
452 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
453 {
455 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
456 {
457 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
458 ((*i)->GetSpellInfo()->SpellIconID == 95))
459 {
460 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
461 if (roll_chance_i(chance))
462 // Mind Trauma
463 m_caster->CastSpell(unitTarget, 48301, true, 0);
464 break;
465 }
466 }
467 }
468 break;
469 }
471 {
472 // Ferocious Bite
473 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
474 {
475 // converts each extra point of energy into ($f1+$AP/410) additional damage
477 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
478 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
479 damage += int32(energy * multiple);
481 }
482 // Wrath
483 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
484 {
485 // Improved Insect Swarm
486 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
488 AddPct(damage, aurEff->GetAmount());
489 }
490 break;
491 }
493 {
494 // Envenom
495 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
496 {
497 if (Player* player = m_caster->ToPlayer())
498 {
499 // consume from stack dozes not more that have combo-points
500 if (uint32 combo = player->GetComboPoints())
501 {
502 // Lookup for Deadly poison (only attacker applied)
504 {
505 // count consumed deadly poison doses at target
506 bool needConsume = true;
507 uint32 spellId = aurEff->GetId();
508
509 uint32 doses = aurEff->GetBase()->GetStackAmount();
510 if (doses > combo)
511 doses = combo;
512
513 // Master Poisoner
514 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
515 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
516 {
517 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
518 {
519 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
520
521 if (chance && roll_chance_i(chance))
522 needConsume = false;
523
524 break;
525 }
526 }
527
528 if (needConsume)
529 for (uint32 i = 0; i < doses; ++i)
531
532 damage *= doses;
533 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
534 }
535
536 // Eviscerate and Envenom Bonus Damage (item set effect)
537 if (m_caster->HasAura(37169))
538 damage += combo * 40;
539 }
540 }
541 }
542 // Eviscerate
543 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
544 {
545 if (m_caster->IsPlayer())
546 {
547 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
548 {
550 damage += int32(ap * combo * 0.07f);
551
552 // Eviscerate and Envenom Bonus Damage (item set effect)
553 if (m_caster->HasAura(37169))
554 damage += combo * 40;
555 }
556 }
557 }
558 break;
559 }
561 {
562 //Gore
563 if (m_spellInfo->SpellIconID == 1578)
564 {
565 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
566 damage *= 2;
567 }
568 // Steady Shot
569 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
570 {
571 bool found = false;
572 // check dazed affect
574 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
575 {
576 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
577 {
578 found = true;
579 break;
580 }
581 }
582
584 if (found)
585 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
586
587 if (Player* caster = m_caster->ToPlayer())
588 {
589 // Add Ammo and Weapon damage plus RAP * 0.1
590 float dmg_min = 0.f;
591 float dmg_max = 0.f;
592 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
593 {
594 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
595 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
596 }
597
598 if (dmg_max == 0.0f && dmg_min > dmg_max)
599 {
600 damage += int32(dmg_min);
601 }
602 else
603 {
604 damage += irand(int32(dmg_min), int32(dmg_max));
605 }
606 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
607 }
608 }
609 break;
610 }
612 {
613 // Hammer of the Righteous
614 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
615 {
616 // Add main hand dps * effect[2] amount
617 if (Player* player = m_caster->ToPlayer())
618 {
619 float minTotal = 0.f;
620 float maxTotal = 0.f;
621 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
622 {
623 float tmpMin, tmpMax;
624 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
625 minTotal += tmpMin;
626 maxTotal += tmpMax;
627 }
628
629 float average = (minTotal + maxTotal) / 2;
632 }
633 break;
634 }
635 // Shield of Righteousness
636 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
637 {
638 uint8 level = m_caster->GetLevel();
639 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
640 if (m_caster->GetAuraEffect(64882, EFFECT_0))
641 block_value += 225;
642 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
643 break;
644 }
645 break;
646 }
647 }
648
649 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
650 {
651 // Xinef: protection
652 if (damage < 0)
653 damage = 0;
654
657 }
658
659 m_damage += damage;
660 }
661}
@ MINDAMAGE
Definition: Unit.h:135
@ MAXDAMAGE
Definition: Unit.h:136
@ FORM_SHADOW
Definition: UnitDefines.h:95
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:613
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_ENERGY
Definition: SharedDefines.h:272
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3534
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1306
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15392
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:14793
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4906
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:800
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1383
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3764{
3766 return;
3767
3769
3771 {
3773 {
3774 switch (m_spellInfo->Id)
3775 {
3776 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3777 case 22539:
3778 case 22972:
3779 case 22975:
3780 case 22976:
3781 case 22977:
3782 case 22978:
3783 case 22979:
3784 case 22980:
3785 case 22981:
3786 case 22982:
3787 case 22983:
3788 case 22984:
3789 case 22985:
3790 {
3791 if (!unitTarget || !unitTarget->IsAlive())
3792 return;
3793
3794 // Onyxia Scale Cloak
3795 if (unitTarget->HasAura(22683))
3796 return;
3797
3798 // Shadow Flame
3799 m_caster->CastSpell(unitTarget, 22682, true);
3800 return;
3801 }
3802 // Plant Warmaul Ogre Banner
3803 case 32307:
3804 if (Player* caster = m_caster->ToPlayer())
3805 {
3806 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3807 if (Creature* target = unitTarget->ToCreature())
3808 {
3809 target->setDeathState(DeathState::Corpse);
3810 target->RemoveCorpse();
3811 }
3812 }
3813 break;
3814 // SOTA defender teleport
3815 case 54640:
3816 {
3817 if (Player* player = unitTarget->ToPlayer())
3818 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3819 {
3820 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3821 {
3822 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3823 bg->DefendersPortalTeleport(dportal, player);
3824 }
3825 }
3826 return;
3827 }
3828 /*// Mug Transformation
3829 case 41931:
3830 {
3831 if (!m_caster->IsPlayer())
3832 return;
3833
3834 uint8 bag = 19;
3835 uint8 slot = 0;
3836 Item* item = nullptr;
3837
3838 while (bag) // 256 = 0 due to var type
3839 {
3840 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3841 if (item && item->GetEntry() == 38587)
3842 break;
3843
3844 ++slot;
3845 if (slot == 39)
3846 {
3847 slot = 0;
3848 ++bag;
3849 }
3850 }
3851 if (bag)
3852 {
3853 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3854 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3855 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3856 m_caster->CastSpell(m_caster, 42518, true);
3857 return;
3858 }
3859 break;
3860 }*/
3861 // Roll Dice - Decahedral Dwarven Dice
3862 case 47770:
3863 {
3864 char buf[128];
3865 const char* gender = "his";
3866 if (m_caster->getGender() > 0)
3867 gender = "her";
3868 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3869 m_caster->TextEmote(buf);
3870 break;
3871 }
3872 case 52173: // Coyote Spirit Despawn
3873 case 60243: // Blood Parrot Despawn
3876 return;
3877 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3878 {
3880 return;
3881
3883
3884 return;
3885 }
3886 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3887 {
3888 if (!m_caster->IsPlayer())
3889 return;
3890
3891 // Delete item from inventory at death
3893
3894 return;
3895 }
3896 case 58418: // Portal to Orgrimmar
3897 case 58420: // Portal to Stormwind
3898 {
3899 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3900 return;
3901
3902 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3903 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3904
3906 unitTarget->CastSpell(unitTarget, spellID, true);
3907
3908 return;
3909 }
3910 // Stoneclaw Totem
3911 case 55328: // Rank 1
3912 case 55329: // Rank 2
3913 case 55330: // Rank 3
3914 case 55332: // Rank 4
3915 case 55333: // Rank 5
3916 case 55335: // Rank 6
3917 case 55278: // Rank 7
3918 case 58589: // Rank 8
3919 case 58590: // Rank 9
3920 case 58591: // Rank 10
3921 {
3922 int32 basepoints0 = damage;
3923 // Cast Absorb on totems
3924 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3925 {
3926 if (!unitTarget->m_SummonSlot[slot])
3927 continue;
3928
3930 if (totem && totem->IsTotem())
3931 {
3932 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3933 }
3934 }
3935 // Glyph of Stoneclaw Totem
3936 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3937 {
3938 basepoints0 *= aur->GetAmount();
3939 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3940 }
3941 break;
3942 }
3943 case 61263: // for item Intravenous Healing Potion (44698)
3944 {
3945 if (!m_caster || !unitTarget)
3946 return;
3947
3948 m_caster->CastSpell(m_caster, 61267, true);
3949 m_caster->CastSpell(m_caster, 61268, true);
3950 return;
3951 }
3952 }
3953 break;
3954 }
3955 case SPELLFAMILY_ROGUE:
3956 {
3957 switch (m_spellInfo->Id)
3958 {
3959 // Master of Subtlety
3960 case 31666:
3961 {
3962 if (!unitTarget)
3963 return;
3964
3965 Aura* mos = unitTarget->GetAura(31665);
3966 if (mos)
3967 {
3968 mos->SetMaxDuration(6000);
3969 mos->SetDuration(6000, true);
3970 }
3971
3972 break;
3973 }
3974 // Overkill
3975 case 58428:
3976 {
3977 if (!unitTarget)
3978 return;
3979
3980 Aura* overkill = unitTarget->GetAura(58427);
3981 if (overkill)
3982 {
3983 overkill->SetMaxDuration(20000);
3984 overkill->SetDuration(20000, true);
3985 }
3986
3987 break;
3988 }
3989 }
3990 break;
3991 }
3992 }
3993
3994 // normal DB scripted effect
3995 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
3997}
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3489
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:585
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition: Creature.cpp:2177
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2455
std::string const & GetName() const
Definition: Object.h:458
uint8 getGender() const
Definition: Unit.h:752
bool IsSummon() const
Definition: Unit.h:707
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:21124

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4826{
4828 return;
4829
4830 if (!m_caster || m_caster->IsAlive())
4831 return;
4832 if (!m_caster->IsPlayer())
4833 return;
4834 if (!m_caster->IsInWorld())
4835 return;
4836
4837 uint32 health = 0;
4838 uint32 mana = 0;
4839
4840 // flat case
4841 if (damage < 0)
4842 {
4843 health = uint32(-damage);
4844 mana = m_spellInfo->Effects[effIndex].MiscValue;
4845 }
4846 // percent case
4847 else
4848 {
4852 }
4853
4854 Player* player = m_caster->ToPlayer();
4855 player->ResurrectPlayer(0.0f);
4856
4857 player->SetHealth(health);
4858 player->SetPower(POWER_MANA, mana);
4859 player->SetPower(POWER_RAGE, 0);
4860 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4861
4862 player->SpawnCorpseBones();
4863}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4672
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4459
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15530

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1375{
1376 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1379 return;
1380
1381 WorldObject* target = nullptr;
1382
1383 // call events for object target if present
1385 {
1386 if (unitTarget)
1387 target = unitTarget;
1388 else if (gameObjTarget)
1389 target = gameObjTarget;
1390 }
1391 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1392 {
1393 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1394 // this check was requested by scripters, but it has some downsides:
1395 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1396 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1397 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1398 return;
1399 // some spells have no target entries in dbc and they use focus target
1400 if (focusObject)
1401 target = focusObject;
1403 }
1404
1405 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1406
1407 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1408 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1409 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1410 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1411
1412 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1413}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:405
ZoneScript * GetZoneScript() const
Definition: Object.h:537
Definition: ZoneScript.h:27

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5085{
5087 return;
5088
5089 if (!unitTarget)
5090 return;
5091
5092 if (Player* player = unitTarget->ToPlayer())
5093 {
5094 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5095 }
5096}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5518{
5520 return;
5521
5522 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5523}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4866{
4868 return;
4869
4870 if (!unitTarget->IsCreature())
4871 return;
4872 if (!m_caster->IsPlayer())
4873 return;
4874
4875 Creature* creature = unitTarget->ToCreature();
4876 int32 targetLevel = creature->GetLevel();
4877
4878 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4879
4883
4884 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4885
4886 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4887
4888 // Double chances for elites
4889 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4890}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:114
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:120

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5549{
5551 return;
5552
5553 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5554 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5555 return;
5556
5558}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7734

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6104{
6106 return;
6107
6108 if (!unitTarget)
6109 return;
6110
6111 if (Player* player = unitTarget->ToPlayer())
6112 {
6113 player->UpdateSpecCount(damage);
6114 }
6115}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5530{
5532 return;
5533
5534 /*
5535 if (!unitTarget->IsPlayer())
5536 return;
5537 if (!unitTarget->IsInWorld())
5538 return;
5539
5540 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5541 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5542 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5543 unitTarget->ToPlayer()->SpawnCorpseBones();
5544 */
5545}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5561{
5563 return;
5564
5565 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5566
5567 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5568 return;
5569
5570 DispelChargesList steal_list;
5571
5572 // Create dispel mask by dispel type
5573 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5574 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5575 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5576 {
5577 Aura* aura = itr->second;
5579 if (!aurApp)
5580 continue;
5581
5582 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5583 {
5584 // Need check for passive? this
5585 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5586 continue;
5587
5588 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5589 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5590 // Polymorph instead of 1 / (5 + 1) -> 16%.
5591 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5592 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5593 if (charges > 0)
5594 steal_list.push_back(std::make_pair(aura, charges));
5595 }
5596 }
5597
5598 if (steal_list.empty())
5599 return;
5600
5601 // Ok if exist some buffs for dispel try dispel it
5602 uint32 failCount = 0;
5603 DispelList success_list;
5604 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5605 // dispel N = damage buffs (or while exist buffs for dispel)
5606 for (int32 count = 0; count < damage && !steal_list.empty();)
5607 {
5608 // Random select buff for dispel
5609 DispelChargesList::iterator itr = steal_list.begin();
5610 std::advance(itr, urand(0, steal_list.size() - 1));
5611
5612 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5613 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5614 if (!chance)
5615 {
5616 steal_list.erase(itr);
5617 continue;
5618 }
5619 else
5620 {
5621 if (roll_chance_i(chance))
5622 {
5623 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5624 --itr->second;
5625 if (itr->second <= 0)
5626 steal_list.erase(itr);
5627 }
5628 else
5629 {
5630 if (!failCount)
5631 {
5632 // Failed to dispell
5633 dataFail << m_caster->GetGUID(); // Caster GUID
5634 dataFail << unitTarget->GetGUID(); // Victim GUID
5635 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5636 }
5637 ++failCount;
5638 dataFail << uint32(itr->first->GetId()); // Spell Id
5639 }
5640 ++count;
5641 }
5642 }
5643
5644 if (failCount)
5645 m_caster->SendMessageToSet(&dataFail, true);
5646
5647 if (success_list.empty())
5648 return;
5649
5650 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5651 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5652 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5653 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5654 dataSuccess << uint8(0); // not used
5655 dataSuccess << uint32(success_list.size()); // count
5656 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5657 {
5658 dataSuccess << uint32(itr->first); // Spell Id
5659 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5660 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5661 }
5662 m_caster->SendMessageToSet(&dataSuccess, true);
5663}
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2540
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:651
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:4987
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1082

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4157{
4159 return;
4160
4161 if (!m_caster->IsPlayer())
4162 return;
4163
4164 Player* target = m_caster->ToPlayer();
4165 if (target->IsInFlight())
4166 return;
4167
4168 // xinef: if player is dead - teleport to graveyard
4169 if (!target->IsAlive())
4170 {
4172 return;
4173
4174 // xinef: player is in corpse
4175 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4176 target->BuildPlayerRepop();
4177 target->RepopAtGraveyard();
4178 return;
4179 }
4180
4181 // xinef: no hearthstone in bag or on cooldown
4182 Item* hearthStone = target->GetItemByEntry(6948);
4183 if (!hearthStone || target->HasSpellCooldown(8690))
4184 {
4185 float o = rand_norm() * 2 * M_PI;
4186 Position pos = *target;
4187 target->MovePositionToFirstCollision(pos, 5.0f, o);
4188 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4189 return;
4190 }
4191
4192 // xinef: we have hearthstone not on cooldown, just use it
4194}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2860
void RepopAtGraveyard()
Definition: Player.cpp:4906
void BuildPlayerRepop()
Definition: Player.cpp:4410

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_AURA_PREVENT_RESURRECTION, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2178{
2180 return;
2181
2182 if (!m_caster->IsPlayer())
2183 return;
2184
2185 Player* player = m_caster->ToPlayer();
2186
2187 // applied only to using item
2188 if (!m_CastItem)
2189 return;
2190
2191 // ... only to item in own inventory/bank/equip_slot
2192 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2193 return;
2194
2195 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2196 if (!newitemid)
2197 return;
2198
2199 uint16 pos = m_CastItem->GetPos();
2200
2201 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2202 if (!pNewItem)
2203 return;
2204
2205 // Client-side enchantment durations update
2207
2211
2213 {
2215 player->DurabilityLoss(pNewItem, lossPercent);
2216 }
2217
2218 if (player->IsInventoryPos(pos))
2219 {
2220 ItemPosCountVec dest;
2221 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2222 if (msg == EQUIP_ERR_OK)
2223 {
2224 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2225
2226 // prevent crash at access and unexpected charges counting with item update queue corrupt
2228 m_targets.SetItemTarget(nullptr);
2229
2230 m_CastItem = nullptr;
2232
2233 player->StoreItem(dest, pNewItem, true);
2234 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2235 return;
2236 }
2237 }
2238 else if (player->IsBankPos(pos))
2239 {
2240 ItemPosCountVec dest;
2241 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2242 if (msg == EQUIP_ERR_OK)
2243 {
2244 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2245
2246 // prevent crash at access and unexpected charges counting with item update queue corrupt
2248 m_targets.SetItemTarget(nullptr);
2249
2250 m_CastItem = nullptr;
2252
2253 player->BankItem(dest, pNewItem, true);
2254 return;
2255 }
2256 }
2257 else if (player->IsEquipmentPos(pos))
2258 {
2259 uint16 dest;
2260
2261 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2262
2263 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2264
2265 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2266 {
2268
2269 // prevent crash at access and unexpected charges counting with item update queue corrupt
2271 m_targets.SetItemTarget(nullptr);
2272
2273 m_CastItem = nullptr;
2275
2276 player->EquipItem(dest, pNewItem, true);
2277 player->AutoUnequipOffhandIfNeed();
2278 return;
2279 }
2280 }
2281
2282 // fail
2283 delete pNewItem;
2284}
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
uint8 GetSlot() const
Definition: Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1088
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
uint16 GetPos() const
Definition: Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
uint8 GetBagSlot() const
Definition: Item.cpp:785
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1258
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1807
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1327
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1278
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4736
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2576
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3025
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1256
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12462
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2729
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2034
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1829
static bool IsBankPos(uint16 pos)
Definition: Player.h:1261

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4544{
4546 return;
4547
4548 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4549
4550 uint8 slot = 0;
4551 switch (m_spellInfo->Effects[effIndex].Effect)
4552 {
4554 slot = 0;
4555 break;
4557 slot = 1;
4558 break;
4560 slot = 2;
4561 break;
4563 slot = 3;
4564 break;
4565 default:
4566 return;
4567 }
4568
4569 if (m_caster)
4570 {
4571 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4572 if (guid)
4573 {
4574 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4575 {
4576 // Recast case - null spell id to make auras not be removed on object remove from world
4577 if (m_spellInfo->Id == gameObject->GetSpellId())
4578 gameObject->SetSpellId(0);
4579 m_caster->RemoveGameObject(gameObject, true);
4580 }
4581 m_caster->m_ObjectSlot[slot].Clear();
4582 }
4583 }
4584
4585 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4586
4587 float x, y, z;
4588 // If dest location if present
4589 if (m_targets.HasDst())
4590 destTarget->GetPosition(x, y, z);
4591 // Summon in random point all other units if location present
4592 else
4594
4595 Map* map = m_caster->GetMap();
4596 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4597 {
4598 delete pGameObj;
4599 return;
4600 }
4601
4602 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4603 int32 duration = m_spellInfo->GetDuration();
4604 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4605 pGameObj->SetSpellId(m_spellInfo->Id);
4606 m_caster->AddGameObject(pGameObj);
4607
4608 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4609
4610 map->AddToMap(pGameObj, true);
4611
4612 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4613}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1798

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3714{
3716 return;
3717
3718 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3719
3720 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3721
3722 WorldObject* target = focusObject;
3723 if (!target)
3724 target = m_caster;
3725
3726 float x, y, z;
3727 if (m_targets.HasDst())
3728 destTarget->GetPosition(x, y, z);
3729 else
3731
3732 Map* map = target->GetMap();
3733
3734 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3735 {
3736 delete pGameObj;
3737 return;
3738 }
3739
3740 int32 duration = m_spellInfo->GetDuration();
3741
3742 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3743 pGameObj->SetSpellId(m_spellInfo->Id);
3744
3745 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3746
3747 // Wild object not have owner and check clickable by players
3748 map->AddToMap(pGameObj, true);
3749
3750 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3751 if (Player* player = m_caster->ToPlayer())
3752 if (Battleground* bg = player->GetBattleground())
3753 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3754
3755 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3756 {
3757 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3758 linkedTrap->SetSpellId(m_spellInfo->Id);
3759 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3760 }
3761}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2735
GameobjectTypes GetGoType() const
Definition: GameObject.h:204

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3116{
3118 return;
3119
3120 if (!m_originalCaster)
3121 return;
3122
3123 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3124 int32 duration = m_spellInfo->GetDuration();
3125
3126 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3127 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3128
3129 Player* owner = m_originalCaster->ToPlayer();
3130 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3132
3133 if (!owner)
3134 {
3135 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3136 if (properties)
3137 {
3138 // Xinef: unsummon old guardian
3139 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3140 oldPet->UnSummon();
3141 SummonGuardian(effIndex, petentry, properties, 1, false);
3142 }
3143 return;
3144 }
3145
3146 Pet* OldSummon = owner->GetPet();
3147
3148 // if pet requested type already exist
3149 if (OldSummon)
3150 {
3151 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3152 {
3153 // pet in corpse state can't be summoned
3154 if (OldSummon->isDead())
3155 return;
3156
3157 ASSERT(OldSummon->GetMap() == owner->GetMap());
3158
3159 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3160
3161 float px, py, pz;
3162 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3163
3164 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3165 OldSummon->UpdateObjectVisibility();
3166
3167 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3168 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3169 // notify player
3170 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3171 owner->SendClearCooldown(itr->first, OldSummon);
3172
3173 // actually clear cooldowns
3174 OldSummon->m_CreatureSpellCooldowns.clear();
3175 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3176 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3177 {
3178 Aura const* aura = i->second->GetBase();
3179 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3180 OldSummon->RemoveAura(i);
3181 else
3182 ++i;
3183 }
3184 return;
3185 }
3186
3187 if (owner->IsPlayer())
3188 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3189 else
3190 return;
3191 }
3192
3193 float x, y, z;
3194 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3195 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3196 if (!pet)
3197 return;
3198
3199 if (m_caster->IsCreature())
3200 {
3201 if (m_caster->ToCreature()->IsTotem())
3203 else
3205 }
3206
3208
3209 // Reset cooldowns
3211 {
3212 pet->m_CreatureSpellCooldowns.clear();
3213 owner->PetSpellInitialize();
3214 }
3215
3216 // Set health to max if new pet is summoned
3217 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3218 // pet should have full health
3219 pet->SetHealth(pet->GetMaxHealth());
3220
3221 // generate new name for summon pet
3222 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3223 if (!new_name.empty())
3224 pet->SetName(new_name);
3225
3226 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3227}
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
@ SPELLMOD_DURATION
Definition: SpellDefines.h:77
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:254
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:97
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:459
float GetObjectSize() const
Definition: Object.cpp:2771
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14654
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17301
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19095
Powers getPowerType() const
Definition: Unit.h:888
bool isDead() const
Definition: Unit.h:1218
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5929

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4197{
4198 // workaround - this effect should not use target map
4200 return;
4201
4202 if (!unitTarget)
4203 return;
4204
4205 Player* player = unitTarget->ToPlayer();
4206 if (!player)
4207 {
4208 return;
4209 }
4210
4211 // Evil Twin (ignore player summon, but hide this for summoner)
4212 // Xinef: Unit Target may be on other map!!!, Need workaround
4213 if (unitTarget->HasAura(23445))
4214 return;
4215
4216 float x, y, z;
4217 m_caster->GetPosition(x, y, z);
4218
4219 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4220
4221 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4222 data << m_caster->GetGUID(); // summoner guid
4223 data << uint32(m_caster->GetZoneId()); // summoner zone
4224 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4225 player->GetSession()->SendPacket(&data);
4226}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:929
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16322

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6298{
6300 return;
6301
6302 if (!m_caster->IsPlayer())
6303 return;
6304
6305 if (!unitTarget)
6306 return;
6307
6308 Player* player = unitTarget->ToPlayer();
6309 if (!player)
6310 {
6311 return;
6312 }
6313
6314 float x, y, z;
6315 m_caster->GetPosition(x, y, z);
6317 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6318 data << m_caster->GetGUID();
6319 data << uint32(m_caster->GetZoneId());
6320 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6321 player->GetSession()->SendPacket(&data);
6322}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2309{
2311 return;
2312
2313 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2314 if (!entry)
2315 return;
2316
2317 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2318 if (!properties)
2319 {
2320 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2321 return;
2322 }
2323
2324 if (!m_originalCaster)
2325 return;
2326
2327 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2328 int32 duration = m_spellInfo->GetDuration();
2329 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2330 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2331
2332 TempSummon* summon = nullptr;
2333
2334 // determine how many units should be summoned
2335 uint32 numSummons;
2336
2337 // some spells need to summon many units, for those spells number of summons is stored in effect value
2338 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2339 // and in spell attributes, possibly we need to add a table for those)
2340 // so here's a list of MiscValueB values, which is currently most generic check
2341 switch (properties->Id)
2342 {
2343 case 64:
2344 case 61:
2345 case 1101:
2346 case 66:
2347 case 648:
2348 case 2301:
2349 case 1061:
2350 case 1261:
2351 case 629:
2352 case 181:
2353 case 715:
2354 case 1562:
2355 case 833:
2356 case 1161:
2357 case 713: // xinef, bloodworms
2358 numSummons = (damage > 0) ? damage : 1;
2359 break;
2360 default:
2361 numSummons = 1;
2362 break;
2363 }
2364
2365 switch (properties->Category)
2366 {
2370 if (properties->Flags & 512)
2371 {
2372 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2373 break;
2374 }
2375 switch (properties->Type)
2376 {
2377 case SUMMON_TYPE_PET:
2380 case SUMMON_TYPE_MINION:
2381 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2382 break;
2383 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2386 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2387 break;
2389 case SUMMON_TYPE_TOTEM:
2390 {
2391 // protection code
2392 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2393 if (!summon || !summon->IsTotem())
2394 return;
2395
2396 // Mana Tide Totem
2397 if (m_spellInfo->Id == 16190)
2399
2400 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2401 {
2402 summon->SetMaxHealth(damage);
2403 summon->SetHealth(damage);
2404 }
2405 break;
2406 }
2407 case SUMMON_TYPE_JEEVES:
2409 {
2410 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2411 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2412 return;
2413
2414 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2416
2417 summon->SetImmuneToAll(true);
2419
2420 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2421 //summon->AI()->EnterEvadeMode();
2422 if (properties->Type != SUMMON_TYPE_JEEVES)
2423 {
2424 summon->GetMotionMaster()->Clear(false);
2426 }
2427 break;
2428 }
2429 default:
2430 {
2431 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2432
2433 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2434
2435 for (uint32 count = 0; count < numSummons; ++count)
2436 {
2437 Position pos;
2438 if (count == 0)
2439 pos = *destTarget;
2440 else
2441 // randomize position for multiple summons
2442 pos = m_caster->GetRandomPoint(*destTarget, radius);
2443
2444 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2445 if (!summon)
2446 continue;
2447
2448 summon->SetTempSummonType(summonType);
2449
2450 if (properties->Category == SUMMON_CATEGORY_ALLY)
2451 {
2454 }
2455
2456 ExecuteLogEffectSummonObject(effIndex, summon);
2457 }
2458 return;
2459 }
2460 }//switch
2461 break;
2463 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2464 if (m_originalCaster)
2466 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2467 break;
2469 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2470 break;
2472 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2473 // to cast a ride vehicle spell on the summoned unit.
2474 //float x, y, z;
2475 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2476 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2477 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2479
2480 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2481 if (!summon || !summon->IsVehicle())
2482 return;
2483
2484 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2486 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2487 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2488 {
2489 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2490 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2491 spellId = spellInfo->Id;
2492 }
2493
2494 // xinef: if we have small value, it indicates seat position
2495 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2496 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2497 else
2498 m_originalCaster->CastSpell(summon, spellId, true);
2499
2500 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2501 //uint32 faction = properties->Faction;
2502 //if (!faction)
2503 uint32 faction = m_originalCaster->GetFaction();
2504
2505 summon->SetFaction(faction);
2506 break;
2507 }
2508
2509 if (summon)
2510 {
2512 ExecuteLogEffectSummonObject(effIndex, summon);
2513 }
2514}
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
TempSummonType
Definition: Object.h:44
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:51
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2023
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1509
uint32 npcflag
Definition: CreatureData.h:200
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:10025
virtual float GetFollowAngle() const
Definition: Unit.h:1722
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10542
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:677
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15492
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1225
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:697
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10827
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:810
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition: Object.cpp:2163
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1914
uint32 Type
Definition: DBCStructure.h:1912
uint32 Id
Definition: DBCStructure.h:1909

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, MAX_VEHICLE_SEATS, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3060{
3062 return;
3063
3064 if (m_caster->GetPetGUID())
3065 return;
3066
3067 if (!unitTarget)
3068 return;
3069
3070 if (!unitTarget->IsCreature())
3071 return;
3072
3073 Creature* creatureTarget = unitTarget->ToCreature();
3074
3075 if (creatureTarget->IsPet())
3076 return;
3077
3079 return;
3080
3081 // cast finish successfully
3082 //SendChannelUpdate(0);
3083 finish();
3084
3085 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3086 if (!pet) // in very specific state like near world end/etc.
3087 return;
3088
3089 // "kill" original creature
3090 creatureTarget->DespawnOrUnsummon();
3091
3092 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3093
3094 // prepare visual effect for levelup
3095 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3096
3097 // add to world
3098 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3099
3100 // visual effect for levelup
3101 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3102
3103 // caster have pet now
3104 m_caster->SetMinion(pet, true);
3105
3106 pet->InitTalentForLevel();
3107
3108 if (m_caster->IsPlayer())
3109 {
3112 }
3113}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3256{
3258 return;
3259
3260 if (!unitTarget)
3261 return;
3262
3263 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3264 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3265 {
3266 m_caster->CastSpell(unitTarget, 67485, true);
3268 }
3269
3270 // this effect use before aura Taunt apply for prevent taunt already attacking target
3271 // for spell as marked "non effective at already attacking target"
3273 {
3275 return;
3276 }
3277
3279 {
3280 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3281 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3283 if (topThreat > myThreat)
3284 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3285
3286 //Set aggro victim to caster
3288 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3289 }
3290}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:49
float GetThreat() const
Definition: ThreatMgr.h:63
HostileReference * getMostHated() const
Definition: ThreatMgr.h:169
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:261
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:276
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition: Unit.cpp:14578

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1166{
1168 return;
1169
1170 if (!unitTarget || unitTarget->IsInFlight())
1171 return;
1172
1173 if (unitTarget->IsPlayer())
1174 {
1175 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1176 }
1177
1178 // Pre effects
1179 switch (m_spellInfo->Id)
1180 {
1181 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1182 if (Player* target = unitTarget->ToPlayer())
1183 {
1184 uint32 mapid = destTarget->GetMapId();
1185 float x, y, z, orientation;
1186 destTarget->GetPosition(x, y, z, orientation);
1187 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1188 }
1189 return;
1190 }
1191
1192 // If not exist data for dest location - return
1193 if (!m_targets.HasDst())
1194 {
1195 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1196 return;
1197 }
1198
1199 // Init dest coordinates
1200 uint32 mapid = destTarget->GetMapId();
1201 if (mapid == MAPID_INVALID)
1202 mapid = unitTarget->GetMapId();
1203 float x, y, z, orientation;
1204 destTarget->GetPosition(x, y, z, orientation);
1205 if (!orientation && m_targets.GetUnitTarget())
1206 orientation = m_targets.GetUnitTarget()->GetOrientation();
1207 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1208
1209 if (mapid == unitTarget->GetMapId())
1210 {
1211 if (unitTarget->GetVehicleKit()) // we are vehicle!
1212 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1213 else
1214 {
1216 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1217 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1219 }
1220 }
1221 else if (unitTarget->IsPlayer())
1222 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1223 else
1224 {
1225 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1226 return;
1227 }
1228
1229 // post effects for TARGET_DEST_DB
1230 switch (m_spellInfo->Id)
1231 {
1232 // Dimensional Ripper - Everlook
1233 case 23442:
1234 {
1235 int32 r = irand(0, 119);
1236 if (r >= 70) // 7/12 success
1237 {
1238 if (r < 100) // 4/12 evil twin
1239 m_caster->CastSpell(m_caster, 23445, true);
1240 else // 1/12 fire
1241 m_caster->CastSpell(m_caster, 23449, true);
1242 }
1243 return;
1244 }
1245 // Ultrasafe Transporter: Toshley's Station
1246 case 36941:
1247 {
1248 if (roll_chance_i(50)) // 50% success
1249 {
1250 int32 rand_eff = urand(1, 7);
1251 switch (rand_eff)
1252 {
1253 case 1:
1254 // soul split - evil
1255 m_caster->CastSpell(m_caster, 36900, true);
1256 break;
1257 case 2:
1258 // soul split - good
1259 m_caster->CastSpell(m_caster, 36901, true);
1260 break;
1261 case 3:
1262 // Increase the size
1263 m_caster->CastSpell(m_caster, 36895, true);
1264 break;
1265 case 4:
1266 // Decrease the size
1267 m_caster->CastSpell(m_caster, 36893, true);
1268 break;
1269 case 5:
1270 // Transform
1271 {
1273 m_caster->CastSpell(m_caster, 36897, true);
1274 else
1275 m_caster->CastSpell(m_caster, 36899, true);
1276 break;
1277 }
1278 case 6:
1279 // chicken
1280 m_caster->CastSpell(m_caster, 36940, true);
1281 break;
1282 case 7:
1283 // evil twin
1284 m_caster->CastSpell(m_caster, 23445, true);
1285 break;
1286 }
1287 }
1288 return;
1289 }
1290 }
1291}
#define MAPID_INVALID
Definition: Position.h:248
@ TELE_TO_SPELL
Definition: Player.h:825
@ TELE_TO_GM_MODE
Definition: Player.h:821
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2090
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1330
Vehicle * GetVehicleKit() const
Definition: Unit.h:1686
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:545

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3645{
3647 return;
3648
3649 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3650 return;
3651
3652 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3654 return;
3655
3657}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14617

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5863{
5865 return;
5866
5867 if (m_caster->IsPlayer())
5868 {
5869 if (Aura* aur = m_caster->GetAura(49152))
5870 aur->RecalculateAmountOfEffects();
5871 else
5872 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5873
5875 }
5876}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13145

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2797{
2799 return;
2800
2801 if (!m_caster->IsPlayer())
2802 return;
2803 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2804 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2805 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2806}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5337{
5339 return;
5340
5341 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5342
5343 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5344
5345 if (!goinfo)
5346 {
5347 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5348 return;
5349 }
5350
5351 float fx, fy, fz;
5352
5353 if (m_targets.HasDst())
5354 destTarget->GetPosition(fx, fy, fz);
5355 //FIXME: this can be better check for most objects but still hack
5356 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5357 {
5358 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5360 }
5361 else
5362 {
5363 //GO is always friendly to it's creator, get range for friends
5364 float min_dis = m_spellInfo->GetMinRange(true);
5365 float max_dis = m_spellInfo->GetMaxRange(true);
5366 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5367
5369 }
5370
5371 // Seaforium charge
5372 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5373 {
5374 fx = m_caster->GetPositionX();
5375 fy = m_caster->GetPositionY();
5376 fz = m_caster->GetPositionZ();
5377 }
5378
5379 Map* cMap = m_caster->GetMap();
5380
5381 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5382
5383 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5384 {
5385 delete pGameObj;
5386 return;
5387 }
5388
5389 int32 duration = m_spellInfo->GetDuration();
5390
5391 switch (goinfo->type)
5392 {
5394 {
5396 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5397
5398 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5399 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5400 int32 lastSec = 0;
5401 switch (urand(0, 2))
5402 {
5403 case 0:
5404 lastSec = 3;
5405 break;
5406 case 1:
5407 lastSec = 7;
5408 break;
5409 case 2:
5410 lastSec = 13;
5411 break;
5412 }
5413
5414 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5415 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5416
5417 break;
5418 }
5420 {
5421 if (m_caster->IsPlayer())
5422 {
5423 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5424 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5425 }
5426 break;
5427 }
5428 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5429 m_caster->AddGameObject(pGameObj);
5430 break;
5433 default:
5434 break;
5435 }
5436
5437 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5438
5439 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5440
5441 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5442 pGameObj->SetSpellId(m_spellInfo->Id);
5443
5444 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5445
5446 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5447 //m_caster->AddGameObject(pGameObj);
5448 //m_ObjToDel.push_back(pGameObj);
5449
5450 cMap->AddToMap(pGameObj, true);
5451
5452 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5453 {
5454 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5455 linkedTrap->SetSpellId(m_spellInfo->Id);
5456 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5457
5458 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5459 }
5460
5461 if (Player* player = m_caster->ToPlayer())
5462 {
5463 player->SetCanTeleport(true);
5464 }
5465}
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:118
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1576
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1578
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:164
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:927
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2313

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
944{
947 return;
948
949 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
950
951 // normal case
952 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
953 if (!spellInfo)
954 {
955 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
956 return;
957 }
958
959 SpellCastTargets targets;
961 {
962 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
963 return;
964 targets.SetUnitTarget(unitTarget);
965 }
966 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
967 {
968 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
969 return;
970
972 targets.SetDst(m_targets);
973
974 targets.SetUnitTarget(m_caster);
975 }
976
977 CustomSpellValues values;
978 // set basepoints for trigger with value effect
980 {
981 // maybe need to set value only when basepoints == 0?
985 }
986
987 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
988 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
989 {
990 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
991 }
992
993 // original caster guid only for GO cast
994 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
995}
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:926
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1037
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1052{
1054 return;
1055
1056 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1057 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1058
1059 if (!spellInfo)
1060 {
1061 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1062 return;
1063 }
1064
1065 finish();
1066
1067 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1068}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
787{
790 return;
791
792 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
793
795 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
797 {
798 // special cases
799 switch (triggered_spell_id)
800 {
801 // Mirror Image
802 case 58832:
803 {
804 // Glyph of Mirror Image
805 if (m_caster->HasAura(63093))
806 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
807
808 break;
809 }
810 // Demonic Empowerment -- succubus
811 case 54437:
812 {
816
817 // Cast Lesser Invisibility
818 unitTarget->CastSpell(unitTarget, 7870, true);
819 return;
820 }
821 // just skip
822 case 23770: // Sayge's Dark Fortune of *
823 // not exist, common cooldown can be implemented in scripts if need.
824 return;
825 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
826 case 29284:
827 {
828 // Brittle Armor
829 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
830 if (!spell)
831 return;
832
833 for (uint32 j = 0; j < spell->StackAmount; ++j)
834 m_caster->CastSpell(unitTarget, spell->Id, true);
835 return;
836 }
837 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
838 case 29286:
839 {
840 // Mercurial Shield
841 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
842 if (!spell)
843 return;
844
845 for (uint32 j = 0; j < spell->StackAmount; ++j)
846 m_caster->CastSpell(unitTarget, spell->Id, true);
847 return;
848 }
849 // Cloak of Shadows
850 case 35729:
851 {
854 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
855 {
856 // remove all harmful spells on you...
857 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
858
859 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
860 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
861 return;
862
863 bool dmgClassNone = false;
865 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
866 {
867 if ((iter->second->GetEffectMask() & (1 << i)) &&
868 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
869 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
870 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
871 {
872 dmgClassNone = false;
873 break;
874 }
875 dmgClassNone = true;
876 }
877
878 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
879 // ignore positive and passive auras
880 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
881 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
883 {
884 m_caster->RemoveAura(iter);
885 }
886 else
887 ++iter;
888 }
889 return;
890 }
891 }
892 }
893
894 // normal case
895 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
896 if (!spellInfo)
897 {
898 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
899 return;
900 }
901
902 SpellCastTargets targets;
904 {
905 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
906 return;
907 targets.SetUnitTarget(unitTarget);
908 }
909 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
910 {
911 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
912 return;
913
915 targets.SetDst(m_targets);
916
917 if (Unit* target = m_targets.GetUnitTarget())
918 targets.SetUnitTarget(target);
919 else
920 targets.SetUnitTarget(m_caster);
921 }
922
923 CustomSpellValues values;
924 // set basepoints for trigger with value effect
926 {
927 // maybe need to set value only when basepoints == 0?
931 }
932
933 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
934 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
935 {
936 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
937 }
938
939 // original caster guid only for GO cast
941}
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ MECHANIC_BLEED
Definition: SharedDefines.h:1340
@ DISPEL_ALL
Definition: SharedDefines.h:1379

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1316{
1318 return;
1319
1320 if (!unitTarget)
1321 return;
1322
1323 Player* player = unitTarget->ToPlayer();
1324 if (!player)
1325 {
1326 return;
1327 }
1328
1329 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1330
1331 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1332 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1333 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1334}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3312

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2721{
2723 return;
2724
2725 if (!unitTarget || m_caster->IsPlayer())
2726 return;
2727
2728 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2730}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8878

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
245{
246 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
247}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3293{
3295 return;
3296
3297 if (!unitTarget || !unitTarget->IsAlive())
3298 return;
3299
3300 // multiple weapon dmg effect workaround
3301 // execute only the last weapon damage
3302 // and handle all effects at once
3303 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3304 {
3305 switch (m_spellInfo->Effects[j].Effect)
3306 {
3311 return; // we must calculate only at last weapon effect
3312 break;
3313 }
3314 }
3315
3316 // some spell specific modifiers
3317 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3318 int32 spell_bonus = 0; // bonus specific for spell
3319 bool normalized = false;
3320
3322 {
3324 {
3325 switch (m_spellInfo->Id)
3326 {
3327 // Trial of the Champion, Black Knight, Obliterate
3328 case 67725:
3329 case 67883:
3330 {
3331 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3332 break;
3333 }
3334 }
3335 break;
3336 }
3338 {
3339 // Devastate (player ones)
3340 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3341 {
3342 m_caster->CastSpell(unitTarget, 58567, true);
3343
3344 if (Aura* aur = unitTarget->GetAura(58567))
3345 {
3346 // 58388 - Glyph of Devastate dummy aura.
3347 if (m_caster->HasAura(58388))
3348 aur->ModStackAmount(1);
3349
3350 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3351 }
3352 }
3353 break;
3354 }
3355 case SPELLFAMILY_ROGUE:
3356 {
3357 // Fan of Knives, Hemorrhage, Ghostly Strike
3358 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3359 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3360 {
3361 // Hemorrhage
3362 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3363 {
3365 }
3366 // 50% more damage with daggers
3367 if (m_caster->IsPlayer())
3368 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3369 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3370 AddPct(totalDamagePercentMod, 50.0f);
3371 }
3372 // Mutilate (for each hand)
3373 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3374 {
3375 bool found = false;
3376 // fast check
3378 found = true;
3379 // full aura scan
3380 else
3381 {
3383 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3384 {
3385 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3386 {
3387 found = true;
3388 break;
3389 }
3390 }
3391 }
3392
3393 if (found)
3394 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3395 }
3396 break;
3397 }
3399 {
3400 switch (m_spellInfo->Id)
3401 {
3402 case 20467: // Seal of Command Unleashed
3403 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3405 break;
3406 case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
3407 case 53739:
3409 AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
3410 break;
3411 case 53385: // Divine Storm deals normalized damage
3412 normalized = true;
3413 break;
3414 default:
3415 break;
3416 }
3417 break;
3418 }
3419 case SPELLFAMILY_SHAMAN:
3420 {
3421 // Skyshatter Harness item set bonus
3422 // Stormstrike
3423 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3424 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3425 // Lava lash damage increased by Flametongue weapon
3427 AddPct(totalDamagePercentMod, 25.0f);
3428 break;
3429 }
3430 case SPELLFAMILY_DRUID:
3431 {
3432 // Mangle (Cat): CP
3433 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3434 {
3436 }
3437 // Shred, Maul - Rend and Tear
3439 {
3440 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3441 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3442 }
3443 break;
3444 }
3445 case SPELLFAMILY_HUNTER:
3446 {
3447 // Kill Shot
3448 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3449 {
3450 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3451 }
3452 break;
3453 }
3455 {
3456 // Plague Strike
3457 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3458 {
3459 // Glyph of Plague Strike
3460 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3461 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3462 break;
3463 }
3464 // Blood Strike
3465 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3466 {
3467 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3468 //Death Knight T8 Melee 4P Bonus
3469 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3470 AddPct(disease_amt, aurEff->GetAmount());
3471
3472 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3473
3474 // Glyph of Blood Strike
3475 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3477 AddPct(totalDamagePercentMod, 20.0f);
3478 break;
3479 }
3480 // Death Strike
3481 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3482 {
3483 // Glyph of Death Strike
3484 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3485 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3486 AddPct(totalDamagePercentMod, runic);
3487 break;
3488 }
3489 // Obliterate (12.5% more damage per disease)
3490 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3491 {
3492 bool consumeDiseases = true;
3493 // Annihilation
3495 // Do not consume diseases if roll sucesses
3496 if (roll_chance_i(aurEff->GetAmount()))
3497 consumeDiseases = false;
3498
3499 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3500 //Death Knight T8 Melee 4P Bonus
3501 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3502 AddPct(disease_amt, aurEff->GetAmount());
3503
3504 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3505 break;
3506 }
3507 // Blood-Caked Strike - Blood-Caked Blade
3508 if (m_spellInfo->SpellIconID == 1736)
3509 {
3510 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3511 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3512 spell_bonus = weaponDamage;
3513 break;
3514 }
3515 // Heart Strike
3516 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3517 {
3518 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3519 //Death Knight T8 Melee 4P Bonus
3520 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3521 AddPct(disease_amt, aurEff->GetAmount());
3522
3523 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3524 break;
3525 }
3526 // Rune Strike
3527 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3528 {
3529 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3530 }
3531
3532 break;
3533 }
3534 }
3535
3536 float weaponDamagePercentMod = 100.0f;
3537 int32 fixed_bonus = 0;
3538
3539 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3540 {
3541 switch (m_spellInfo->Effects[j].Effect)
3542 {
3545 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3546 break;
3548 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3549 normalized = true;
3550 break;
3552 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3553 break;
3554 default:
3555 break; // not weapon damage effect, just skip
3556 }
3557 }
3558
3559 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3560 if (fixed_bonus || spell_bonus)
3561 {
3562 UnitMods unitMod;
3563 switch (m_attackType)
3564 {
3565 default:
3566 case BASE_ATTACK:
3567 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3568 break;
3569 case OFF_ATTACK:
3570 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3571 break;
3572 case RANGED_ATTACK:
3573 unitMod = UNIT_MOD_DAMAGE_RANGED;
3574 break;
3575 }
3576
3578 {
3579 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3580 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3581 spell_bonus = int32(spell_bonus * weapon_total_pct);
3582 }
3583 }
3584
3585 int32 weaponDamage = 0;
3586 // Dancing Rune Weapon
3587 if (m_caster->GetEntry() == 27893)
3588 {
3589 if (Unit* owner = m_caster->GetOwner())
3590 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3591 }
3592 else if (m_spellInfo->Id == 5019) // Wands
3593 {
3594 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3595 }
3596 else
3597 {
3598 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3599 }
3600
3601 // Sequence is important
3602 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3603 {
3604 // We assume that a spell have at most one fixed_bonus
3605 // and at most one weaponDamagePercentMod
3606 switch (m_spellInfo->Effects[j].Effect)
3607 {
3611 weaponDamage += fixed_bonus;
3612 break;
3614 ApplyPct(weaponDamage, weaponDamagePercentMod);
3615 default:
3616 break; // not weapon damage effect, just skip
3617 }
3618 }
3619
3620 weaponDamage += spell_bonus;
3621 ApplyPct(weaponDamage, totalDamagePercentMod);
3622
3623 // prevent negative damage
3624 uint32 eff_damage(std::max(weaponDamage, 0));
3625
3626 // Add melee damage bonuses (also check for negative)
3629
3630 // Meteor like spells (divided damage to targets)
3632 {
3633 uint32 count = 0;
3634 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3635 if (ihit->effectMask & (1 << effIndex))
3636 ++count;
3637
3638 eff_damage /= count; // divide to all targets
3639 }
3640
3641 m_damage += eff_damage;
3642}
UnitMods
Definition: Unit.h:142
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:166
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:167
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:165
@ TOTAL_PCT
Definition: Unit.h:129
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:359
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:275
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1308
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1310
@ DISPEL_POISON
Definition: SharedDefines.h:1376
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13240
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5799
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5528
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:15252
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2967
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11901
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13038

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5143{
5144 InitEffectExecuteData(effIndex);
5145 *m_effectExecuteData[effIndex] << uint32(entry);
5146}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8471

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5149{
5150 InitEffectExecuteData(effIndex);
5151 *m_effectExecuteData[effIndex] << uint32(entry);
5152}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5129{
5130 InitEffectExecuteData(effIndex);
5131 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5132 *m_effectExecuteData[effIndex] << int32(itemId);
5133 *m_effectExecuteData[effIndex] << int32(slot);
5134}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5115{
5116 InitEffectExecuteData(effIndex);
5117 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5118 *m_effectExecuteData[effIndex] << uint32(attCount);
5119}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5122{
5123 InitEffectExecuteData(effIndex);
5124 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5125 *m_effectExecuteData[effIndex] << uint32(spellId);
5126}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5137{
5138 InitEffectExecuteData(effIndex);
5139 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5140}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5167{
5168 InitEffectExecuteData(effIndex);
5169 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5170}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5106{
5107 InitEffectExecuteData(effIndex);
5108 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5109 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5110 *m_effectExecuteData[effIndex] << uint32(PowerType);
5111 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5112}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5161{
5162 InitEffectExecuteData(effIndex);
5163 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5164}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4481{
4482 if (!m_caster)
4483 return;
4484
4486 return;
4488
4489 if (m_spellInfo->IsChanneled())
4491
4494
4495 // Unsummon summon as possessed creatures on spell cancel
4497 {
4498 if (Unit* charm = m_caster->GetCharm())
4499 if (charm->IsCreature()
4500 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4501 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4502 ((Puppet*)charm)->UnSummon();
4503 }
4504
4505 if (Creature* creatureCaster = m_caster->ToCreature())
4506 creatureCaster->ReleaseFocus(this);
4507
4508 if (ok)
4509 {
4512 }
4513 else
4514 {
4515 if (m_caster->IsPlayer())
4516 {
4517 // Xinef: Restore spell mods in case of fail cast
4519
4520 // Xinef: Reset cooldown event in case of fail cast
4523 }
4524 return;
4525 }
4526
4527 // pussywizard:
4530
4532 {
4533 // Unsummon statue
4535 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4536 if (spellInfo && spellInfo->SpellIconID == 2056)
4537 {
4538 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4539 m_caster->setDeathState(DeathState::JustDied);
4540 return;
4541 }
4542 }
4543
4544 // potions disabled by client, send event "not in combat" if need
4547
4548 // Take mods after trigger spell (needed for 14177 to affect 48664)
4549 // mods are taken only on succesfull cast and independantly from targets of the spell
4550 if (Player* player = m_caster->GetSpellModOwner())
4551 player->RemoveSpellMods(this);
4552
4553 // xinef: clear reactive auras states after spell cast
4556
4557 // Stop Attack for some spells
4560}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:309
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1497
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14517
void UpdateInterruptMask()
Definition: Unit.cpp:754
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10466
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3471

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8467{
8469}
void SendLogExecute()
Definition: Spell.cpp:5071

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
547{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8930{
8931 std::stringstream sstr;
8932 sstr << std::boolalpha
8933 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8934 << " State: " << getState();
8935 return sstr.str();
8936}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
562{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
565{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
576{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2109{
2110 // this function selects which containers need to be searched for spell target
2112
2113 // filter searchers based on searched object type
2114 switch (objType)
2115 {
2122 break;
2126 break;
2127 default:
2128 break;
2129 }
2131 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2135 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2136
2137 if (condList)
2138 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2139 return retMask;
2140}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:70
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:69
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
583{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
591{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4174{
4175 if (!UpdatePointers())
4176 {
4177 // finish the spell if UpdatePointers() returned false, something wrong happened there
4178 finish(false);
4179 return 0;
4180 }
4181
4182 Player* modOwner = m_caster->GetSpellModOwner();
4183 if (modOwner)
4184 modOwner->SetSpellModTakingSpell(this, true);
4185
4186 uint64 next_time = m_delayTrajectory;
4187
4189
4190 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4191 {
4193 m_immediateHandled = true;
4195 next_time = 0;
4196 }
4197
4198 bool single_missile = (m_targets.HasDst());
4199
4200 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4201 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4202 {
4203 if (ihit->processed == false)
4204 {
4205 if (single_missile || ihit->timeDelay <= t_offset)
4206 {
4207 ihit->timeDelay = t_offset;
4208 DoAllEffectOnTarget(&(*ihit));
4209 }
4210 else if (next_time == 0 || ihit->timeDelay < next_time)
4211 next_time = ihit->timeDelay;
4212 }
4213 }
4214
4215 // now recheck gameobject targeting correctness
4216 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4217 {
4218 if (ighit->processed == false)
4219 {
4220 if (single_missile || ighit->timeDelay <= t_offset)
4221 DoAllEffectOnTarget(&(*ighit));
4222 else if (next_time == 0 || ighit->timeDelay < next_time)
4223 next_time = ighit->timeDelay;
4224 }
4225 }
4226
4228
4229 if (modOwner)
4230 modOwner->SetSpellModTakingSpell(this, false);
4231
4232 // All targets passed - need finish phase
4233 if (next_time == 0)
4234 {
4235 // spell is finished, perform some last features of the spell here
4237
4238 finish(true); // successfully finish spell cast
4239
4240 // return zero, spell is finished now
4241 return 0;
4242 }
4243 else
4244 {
4245 // spell is unfinished, return next execution time
4246 return next_time;
4247 }
4248}
void _handle_finish_phase()
Definition: Spell.cpp:4278
void PrepareTargetProcessing()
Definition: Spell.cpp:8461
void _handle_immediate_phase()
Definition: Spell.cpp:4250
void FinishTargetProcessing()
Definition: Spell.cpp:8466

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4114{
4115 // start channeling if applicable
4116 if (m_spellInfo->IsChanneled())
4117 {
4118 int32 duration = m_spellInfo->GetDuration();
4120 duration = -1;
4121
4122 if (duration > 0)
4123 {
4124 // First mod_duration then haste - see Missile Barrage
4125 // Apply duration mod
4126 if (Player* modOwner = m_caster->GetSpellModOwner())
4127 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4128
4129 // Apply haste mods
4131 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4132
4135 m_channeledDuration = duration;
4136 SendChannelStart(duration);
4137 }
4138 else if (duration == -1)
4139 {
4142 SendChannelStart(duration);
4143 }
4144 }
4145
4147
4148 // process immediate effects (items, ground, etc.) also initialize some variables
4150
4151 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4152 DoAllEffectOnTarget(&(*ihit));
4153
4154 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4155 DoAllEffectOnTarget(&(*ihit));
4156
4158
4159 // spell is finished, perform some last features of the spell here
4161
4162 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4163 TakeCastItem();
4164
4165 // handle ammo consumption for Hunter's volley spell
4167 TakeAmmo();
4168
4170 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4171}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1516
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5204
void TakeAmmo()
Definition: Spell.cpp:5377

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5626{
5628 return;
5629
5630 effectHandleMode = mode;
5631 unitTarget = pUnitTarget;
5632 itemTarget = pItemTarget;
5633 gameObjTarget = pGOTarget;
5635
5636 uint8 eff = m_spellInfo->Effects[i].Effect;
5637
5638 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5639
5640 // we do not need DamageMultiplier here.
5641 damage = CalculateSpellDamage(i, nullptr);
5642
5643 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5644
5645 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5646 {
5647 (this->*SpellEffects[eff])((SpellEffIndex)i);
5648 }
5649}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8580

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8230{
8231 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8232 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8233 {
8234 // don't do anything for empty effect
8235 if (!m_spellInfo->Effects[i].IsEffect())
8236 continue;
8237
8238 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8239 }
8240
8241 float multiplier[MAX_SPELL_EFFECTS];
8242 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8243 if (m_applyMultiplierMask & (1 << i))
8244 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8245
8248 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8249 {
8250 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8251 usesAmmo = false;
8252 }
8253
8255
8256 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8257 {
8258 TargetInfo& target = *ihit;
8259
8260 uint32 mask = target.effectMask;
8261 if (!mask)
8262 continue;
8263
8264 // do not consume ammo anymore for Hunter's volley spell
8266 usesAmmo = false;
8267
8268 if (usesAmmo)
8269 {
8270 bool ammoTaken = false;
8271 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8272 {
8273 if (!(mask & 1 << i))
8274 continue;
8275 switch (m_spellInfo->Effects[i].Effect)
8276 {
8282 ammoTaken = true;
8283 TakeAmmo();
8284 }
8285 if (ammoTaken)
8286 break;
8287 }
8288 }
8289
8290 DoAllEffectOnLaunchTarget(target, multiplier);
8291 }
8292
8294}
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8296

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5579{
5580 if (m_UniqueTargetInfo.empty())
5581 return;
5582
5584 return;
5585
5586 float threat = 0.0f;
5587 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5588 {
5589 if (threatEntry->apPctMod != 0.0f)
5590 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5591
5592 threat += threatEntry->flatMod;
5593 }
5595 threat += m_spellInfo->SpellLevel;
5596
5597 // past this point only multiplicative effects occur
5598 if (threat == 0.0f)
5599 return;
5600
5601 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5602 threat /= m_UniqueTargetInfo.size();
5603
5604 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5605 {
5606 float threatToAdd = threat;
5607 if (ihit->missCondition != SPELL_MISS_NONE)
5608 threatToAdd = 0.0f;
5609
5610 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5611 if (!target)
5612 continue;
5613
5614 bool IsFriendly = m_caster->IsFriendlyTo(target);
5615 // positive spells distribute threat among all units that are in combat with target, like healing
5617 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5618 // for negative spells threat gets distributed among affected targets
5619 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5620 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5621 }
5622 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5623}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:178
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2839
Definition: SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8100{
8101 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8102 if (itr->effectMask & (1 << effect))
8103 return true;
8104
8105 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8106 if (itr->effectMask & (1 << effect))
8107 return true;
8108
8109 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8110 if (itr->effectMask & (1 << effect))
8111 return true;
8112
8113 return false;
8114}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8472{
8473 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8474 if (!m_effectExecuteData[effIndex])
8475 {
8476 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8477 // first dword - target counter
8478 *m_effectExecuteData[effIndex] << uint32(1);
8479 }
8480 else
8481 {
8482 // increase target counter by one
8483 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8484 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8485 }
8486}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
713{
714 m_targets = targets;
715 // this function tries to correct spell explicit targets for spell
716 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
717 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
718 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
719
720 if (WorldObject* target = m_targets.GetObjectTarget())
721 {
722 // check if object target is valid with needed target flags
723 // for unit case allow corpse target mask because player with not released corpse is a unit target
724 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
725 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
726 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
728 }
729 else
730 {
731 // try to select correct unit target if not provided by client or by serverside cast
732 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
733 {
734 Unit* unit = nullptr;
735 // try to use player selection as a target
736 if (Player* playerCaster = m_caster->ToPlayer())
737 {
738 // selection has to be found and to be valid target for the spell
739 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
741 unit = selectedUnit;
742 }
743 // try to use attacked unit as a target
744 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
745 unit = m_caster->GetVictim();
746
747 // didn't find anything - let's use self as target
748 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
749 unit = m_caster;
750
752 }
753 }
754
755 // check if spell needs dst target
756 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
757 {
758 // and target isn't set
759 if (!m_targets.HasDst())
760 {
761 // try to use unit target if provided
762 if (WorldObject* target = targets.GetObjectTarget())
763 m_targets.SetDst(*target);
764 // or use self if not available
765 else
767 }
768 }
769 else
771
772 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
773 {
774 if (!targets.HasSrc())
776 }
777 else
779}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:320
void RemoveDst()
Definition: Spell.cpp:447
void RemoveSrc()
Definition: Spell.cpp:390

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8074{
8077 {
8078 return false;
8079 }
8080
8082 {
8083 return false;
8084 }
8085
8086 return true;
8087}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
629 {
630 if (m_delayAtDamageCount >= 2)
631 return true;
632
634 return false;
635 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
560{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8222{
8223 if (target->IsAlive())
8225
8227}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1221
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1226

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8495{
8496 if (_scriptsLoaded)
8497 return;
8498 _scriptsLoaded = true;
8499 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8500 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8501 {
8502 if (!(*itr)->_Load(this))
8503 {
8504 std::list<SpellScript*>::iterator bitr = itr;
8505 ++itr;
8506 delete (*bitr);
8507 m_loadedScripts.erase(bitr);
8508 continue;
8509 }
8510 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8511 (*itr)->Register();
8512 ++itr;
8513 }
8514}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8900{
8901 if (!m_caster || !m_caster->IsInWorld())
8902 return;
8903
8904 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8905
8906 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8907 // can succeed with a lockId of 0
8908 if (m_spellInfo->Id == 21651)
8909 {
8910 if (GameObject* go = m_targets.GetGOTarget())
8911 {
8912 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8913 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8914 {
8915 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8916 visual->prepare(&m_targets);
8917 }
8918 }
8919 }
8920}
@ TRIGGERED_NONE
Definition: SpellDefines.h:130
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3476{
3477 if (m_CastItem)
3478 {
3480 }
3481 else
3482 {
3484 }
3485
3486 InitExplicitTargets(*targets);
3487
3488 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3489 {
3490 finish(false);
3491 return SPELL_FAILED_UNKNOWN;
3492 }
3493
3494 // Fill aura scaling information
3496 {
3497 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3498 {
3499 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3502 {
3503 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3505 {
3506 m_auraScaleMask |= (1 << i);
3507 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3508 {
3509 m_auraScaleMask = 0;
3510 break;
3511 }
3512 }
3513 }
3514 }
3515 }
3516
3518
3519 if (triggeredByAura)
3520 {
3521 m_triggeredByAuraSpell.Init(triggeredByAura);
3522 }
3523
3524 // create and add update event for this spell
3525 _spellEvent = new SpellEvent(this);
3527
3529 {
3531 finish(false);
3533 }
3534
3535 //Prevent casting at cast another spell (ServerSide check)
3537 {
3539 finish(false);
3541 }
3542
3543 LoadScripts();
3544
3545 OnSpellLaunch();
3546
3548
3549 // Set combo point requirement
3551 m_needComboPoints = false;
3552
3553 SpellCastResult result = CheckCast(true);
3554 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3555 {
3556 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3557 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3558 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3559 // a possible alternative sollution for those would be validating aura target on unit state change
3560 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3561 {
3563 triggeredByAura->GetBase()->SetDuration(0);
3564 }
3565
3566 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3568 {
3569 SendCastResult(result);
3570
3571 finish(false);
3572 return result;
3573 }
3574 }
3575
3576 // Prepare data for triggers
3577 prepareDataForTriggerSystem(triggeredByAura);
3578
3579 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3581
3582 if (m_caster->IsPlayer())
3584 m_casttime = 0;
3585
3586 // don't allow channeled spells / spells with cast time to be casted while moving
3587 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3589 {
3590 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3592 {
3594 finish(false);
3595 return SPELL_FAILED_MOVING;
3596 }
3597 }
3598
3599 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3600 if (m_CastItem)
3601 {
3602 bool selectTargets = false;
3603 bool nearbyDest = false;
3604
3605 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3606 {
3607 if (!m_spellInfo->Effects[i].IsEffect())
3608 continue;
3609
3610 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3611 {
3612 selectTargets = false;
3613 break;
3614 }
3615
3616 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3617 {
3618 nearbyDest = true;
3619 }
3620
3621 // xinef: by default set it to false, and to true if any valid target is found
3622 selectTargets = true;
3623 }
3624
3625 if (selectTargets)
3626 {
3628 _spellTargetsSelected = true;
3629 bool spellFailed = false;
3630
3631 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3632 {
3633 // no valid nearby target unit or game object found; check if nearby destination type
3634 if (nearbyDest)
3635 {
3636 if (!m_targets.HasDst())
3637 {
3638 // no valid target destination
3639 spellFailed = true;
3640 }
3641 }
3642 else
3643 {
3644 spellFailed = true;
3645 }
3646 }
3647
3648 if (spellFailed)
3649 {
3651 finish(false);
3653 }
3654 }
3655 }
3656
3657 // set timer base at cast time
3658 ReSetTimer();
3659
3660 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3661
3663 {
3665 }
3666
3667 //Containers for channeled spells have to be set
3668 //TODO:Apply this to all casted spells if needed
3669 // Why check duration? 29350: channelled triggers channelled
3671 cast(true);
3672 else
3673 {
3674 // stealth must be removed at cast starting (at show channel bar)
3675 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3677 {
3678 // Farsight spells exception
3679 uint32 exceptSpellId = 0;
3681 {
3682 exceptSpellId = m_spellInfo->Id;
3683 }
3684
3687 }
3688
3691
3692 // set target for proper facing
3694 {
3697 {
3698 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3699 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3701 }
3702 }
3703
3704 //item: first cast may destroy item and second cast causes crash
3705 // xinef: removed !m_spellInfo->StartRecoveryTime
3706 // second los check failed in events
3707 // xinef: removed itemguid check, currently there is no such item in database
3709 cast(true);
3710
3713 }
3714
3715 return SPELL_CAST_OK;
3716}
@ CHEAT_CASTTIME
Definition: Player.h:1000
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:137
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:26
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3550
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3940
bool IsSitState() const
Definition: Unit.cpp:16676
Definition: Spell.cpp:518
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8922
void LoadScripts()
Definition: Spell.cpp:8494
void cast(bool skipCheck=false)
Definition: Spell.cpp:3789
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2290
void SendSpellStart()
Definition: Spell.cpp:4715
void TriggerGlobalCooldown()
Definition: Spell.cpp:8838
void OnSpellLaunch()
Definition: Spell.cpp:8899
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7909
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:712
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1260
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2344
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1270

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2291{
2292 //==========================================================================================
2293 // Now fill data for trigger system, need know:
2294 // can spell trigger another or not (m_canTrigger)
2295 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2296 //==========================================================================================
2297
2299 // Get data for type of attack and fill base info for trigger
2300 switch (m_spellInfo->DmgClass)
2301 {
2304 if (m_attackType == OFF_ATTACK)
2306 else
2309 break;
2311 // Auto attack
2313 {
2316 }
2317 else // Ranged spell attack
2318 {
2321 }
2322 break;
2323 default:
2326 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2327 {
2330 }
2331 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2332 // Because spell positivity is dependant on target
2333 }
2335
2336 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2338 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2339 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2340 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2341 {
2343 }
2344
2345 /* Effects which are result of aura proc from triggered spell cannot proc
2346 to prevent chain proc of these spells */
2347
2348 // Hellfire Effect - trigger as DOT
2350 {
2353 }
2354
2355 // Ranged autorepeat attack is set as triggered spell - ignore it
2357 {
2364 }
2365 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2368}
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:145
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8575{
8576 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8577 (*scritr)->_InitHit();
8578}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8749{
8752 {
8753 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8754 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8756 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8757 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8759 }
8760
8763 {
8765 {
8766 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8767 {
8769 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8770 {
8771 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8772 {
8773 m_preCastSpell = 26017;
8774 break;
8775 }
8776 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8777 m_preCastSpell = 67;
8778 }
8779 }
8780 break;
8781 }
8782 case SPELLFAMILY_DRUID:
8783 {
8784 // Faerie Fire (Feral)
8786 m_preCastSpell = 60089;
8787
8788 break;
8789 }
8790 }
8791
8792 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8793 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8794 // and to correctly calculate proc chance when combopoints are present
8796 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8797 {
8798 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8799 continue;
8800 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8801 uint32 auraSpellIdx = (*i)->GetEffIndex();
8802 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8803 {
8804 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8805 // this possibly needs fixing
8806 int32 auraBaseAmount = (*i)->GetBaseAmount();
8807 // proc chance is stored in effect amount
8808 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8809 // build trigger and add to the list
8810 HitTriggerSpell spellTriggerInfo;
8811 spellTriggerInfo.triggeredSpell = spellInfo;
8812 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8813 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8814 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8815 m_hitTriggerSpells.push_back(spellTriggerInfo);
8816 }
8817 }
8818}
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
916{
919}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:894
uint64 GetDelayStart() const
Definition: Spell.h:562

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, Unit::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
550{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2185{
2186 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2187 if (!containerTypeMask)
2188 return;
2189 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2190 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2191 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2192}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2108

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2195{
2196 // max dist for jump target selection
2197 float jumpRadius = 0.0f;
2198 switch (m_spellInfo->DmgClass)
2199 {
2201 // 7.5y for multi shot
2202 jumpRadius = 7.5f;
2203 break;
2205 // 5y for swipe, cleave and similar
2206 jumpRadius = 5.0f;
2207 break;
2210 // 12.5y for chain heal spell since 3.2 patch
2211 if (isChainHeal)
2212 jumpRadius = 12.5f;
2213 // 10y as default for magic chain spells
2214 else
2215 jumpRadius = 10.0f;
2216 break;
2217 }
2218
2219 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2223
2224 // max dist which spell can reach
2225 float searchRadius = jumpRadius;
2226 if (isBouncingFar)
2227 searchRadius *= chainTargets;
2228
2229 std::list<WorldObject*> tempTargets;
2230 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2231 tempTargets.remove(target);
2232
2233 // remove targets which are always invalid for chain spells
2234 // for some spells allow only chain targets in front of caster (swipe for example)
2235 if (!isBouncingFar)
2236 {
2237 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2238 {
2239 std::list<WorldObject*>::iterator checkItr = itr++;
2240 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2241 tempTargets.erase(checkItr);
2242 }
2243 }
2244
2245 while (chainTargets)
2246 {
2247 // try to get unit for next chain jump
2248 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2249 // get unit with highest hp deficit in dist
2250 if (isChainHeal)
2251 {
2252 uint32 maxHPDeficit = 0;
2253 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2254 {
2255 if (Unit* unit = (*itr)->ToUnit())
2256 {
2257 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2258 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2259 {
2260 foundItr = itr;
2261 maxHPDeficit = deficit;
2262 }
2263 }
2264 }
2265 }
2266 // get closest object
2267 else
2268 {
2269 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2270 {
2271 if (foundItr == tempTargets.end())
2272 {
2273 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2274 foundItr = itr;
2275 }
2276 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2277 foundItr = itr;
2278 }
2279 }
2280 // not found any valid target - chain ends
2281 if (foundItr == tempTargets.end())
2282 break;
2283 target = *foundItr;
2284 tempTargets.erase(foundItr);
2285 targets.push_back(target);
2286 --chainTargets;
2287 }
2288}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:548
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1316
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1381
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2184

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2173{
2174 WorldObject* target = nullptr;
2175 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2176 if (!containerTypeMask)
2177 return nullptr;
2178 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2180 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2181 return target;
2182}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2144{
2145 if (!containerMask)
2146 return;
2147
2148 // search world and grid for possible targets
2149 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2150 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2151
2152 if (searchInGrid || searchInWorld)
2153 {
2154 float x, y;
2155 x = pos->GetPositionX();
2156 y = pos->GetPositionY();
2157
2159 Cell cell(p);
2160 cell.SetNoCreate();
2161
2162 Map* map = referer->GetMap();
2163
2164 if (searchInWorld)
2165 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2166
2167 if (searchInGrid)
2168 Cell::VisitGridObjects(x, y, map, searcher, radius);
2169 }
2170}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:178

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
922{
923 if (!targetType.GetTarget())
924 return;
925
926 uint32 effectMask = 1 << effIndex;
927 // set the same target list for all effects
928 // some spells appear to need this, however this requires more research
929 switch (targetType.GetSelectionCategory())
930 {
934 {
935 // targets for effect already selected
936 if (effectMask & processedEffectMask)
937 {
938 return;
939 }
940
941 auto const& effects = GetSpellInfo()->Effects;
942
943 // choose which targets we can select at once
944 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
945 {
946 if (effects[j].IsEffect() &&
947 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
948 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
949 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
950 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
952 {
953 effectMask |= 1 << j;
954 }
955 }
956 processedEffectMask |= effectMask;
957 break;
958 }
959 default:
960 break;
961 }
962
963 switch (targetType.GetSelectionCategory())
964 {
966 SelectImplicitChannelTargets(effIndex, targetType);
967 break;
969 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
970 break;
972 SelectImplicitConeTargets(effIndex, targetType, effectMask);
973 break;
975 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
976 break;
978 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
979 CheckDst();
980
981 SelectImplicitTrajTargets(effIndex, targetType);
982 break;
984 switch (targetType.GetObjectType())
985 {
987 switch (targetType.GetReferenceType())
988 {
991 break;
992 default:
993 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
994 break;
995 }
996 break;
998 switch (targetType.GetReferenceType())
999 {
1001 SelectImplicitCasterDestTargets(effIndex, targetType);
1002 break;
1004 SelectImplicitTargetDestTargets(effIndex, targetType);
1005 break;
1007 SelectImplicitDestDestTargets(effIndex, targetType);
1008 break;
1009 default:
1010 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1011 break;
1012 }
1013 break;
1014 default:
1015 switch (targetType.GetReferenceType())
1016 {
1018 SelectImplicitCasterObjectTargets(effIndex, targetType);
1019 break;
1021 SelectImplicitTargetObjectTargets(effIndex, targetType);
1022 break;
1023 default:
1024 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1025 break;
1026 }
1027 break;
1028 }
1029 break;
1031 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1032 break;
1033 default:
1034 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1035 break;
1036 }
1037}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1716
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1865
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1209
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1679
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1259
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1039
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1802
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1755
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1095
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8709
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1341

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2026{
2027 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2029 switch (m_spellInfo->Effects[effIndex].Effect)
2030 {
2034 {
2036
2038
2039 if (target && target->ToPlayer())
2040 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2041 }
2042 return;
2043 default:
2044 break;
2045 }
2046
2047 // select spell implicit targets based on effect type
2048 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2049 return;
2050
2051 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2052
2053 if (!targetMask)
2054 return;
2055
2056 WorldObject* target = nullptr;
2057
2058 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2059 {
2060 // add explicit object target or self to the target map
2062 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2064 {
2066 target = unitTarget;
2067 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2068 {
2069 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2070 {
2072 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2073 target = owner;
2074 }
2075 }
2076 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2077 target = m_caster;
2078 }
2079 if (targetMask & TARGET_FLAG_ITEM_MASK)
2080 {
2082 AddItemTarget(itemTarget, 1 << effIndex);
2083 return;
2084 }
2085 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2086 target = m_targets.GetGOTarget();
2087 break;
2088 // add self to the target map
2090 if (targetMask & TARGET_FLAG_UNIT_MASK)
2091 target = m_caster;
2092 break;
2093 default:
2094 break;
2095 }
2096
2098
2099 if (target)
2100 {
2101 if (target->ToUnit())
2102 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2103 else if (target->ToGameObject())
2104 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2105 }
2106}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:210
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:293
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2512
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2379
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2574
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8681
Definition: SpellInfo.h:217

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
782{
783 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
784 if (Unit* target = m_targets.GetUnitTarget())
785 {
786 // check for explicit target redirection, for Grounding Totem for example
790 {
791 Unit* redirect;
792 switch (m_spellInfo->DmgClass)
793 {
796 break;
800 break;
801 default:
802 redirect = nullptr;
803 break;
804 }
805 if (redirect && (redirect != target))
806 {
807 m_targets.SetUnitTarget(redirect);
809 }
810 }
811 }
812}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11021
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:10983

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1260{
1261 Unit* referer = nullptr;
1262 switch (targetType.GetReferenceType())
1263 {
1267 referer = m_caster;
1268 break;
1270 referer = m_targets.GetUnitTarget();
1271 break;
1273 {
1274 // find last added target for this effect
1275 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1276 {
1277 if (ihit->effectMask & (1 << effIndex))
1278 {
1279 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1280 break;
1281 }
1282 }
1283 break;
1284 }
1285 default:
1286 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1287 return;
1288 }
1289 if (!referer)
1290 return;
1291
1292 Position const* center = nullptr;
1293 switch (targetType.GetReferenceType())
1294 {
1296 center = m_targets.GetSrcPos();
1297 break;
1299 center = m_targets.GetDstPos();
1300 break;
1304 center = referer;
1305 break;
1306 default:
1307 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1308 return;
1309 }
1310
1311 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1312 std::list<WorldObject*> targets;
1313 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1314 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1315
1316 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1317
1318 if (!targets.empty())
1319 {
1320 // Other special target selection goes here
1321 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1322 {
1324 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1325 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1326 maxTargets += (*j)->GetAmount();
1327
1328 Acore::Containers::RandomResize(targets, maxTargets);
1329 }
1330
1331 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1332 {
1333 if (Unit* unitTarget = (*itr)->ToUnit())
1334 AddUnitTarget(unitTarget, effMask, false);
1335 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1336 AddGOTarget(gObjTarget, effMask);
1337 }
1338 }
1339}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:79
Position const * GetSrcPos() const
Definition: Spell.cpp:361
float RadiusMod
Definition: Spell.h:215
uint32 MaxAffectedTargets
Definition: Spell.h:214
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8667

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1342{
1344
1345 switch (targetType.GetTarget())
1346 {
1347 case TARGET_DEST_CASTER:
1349 break;
1350 case TARGET_DEST_HOME:
1351 if (Player* playerCaster = m_caster->ToPlayer())
1352 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1353 break;
1354 case TARGET_DEST_DB:
1355 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1356 {
1359 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1360 else if (st->target_mapId == m_caster->GetMapId())
1361 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1362 }
1363 else
1364 {
1365 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1366 if (WorldObject* target = m_targets.GetObjectTarget())
1367 dest = SpellDestination(*target);
1368 }
1369 break;
1371 {
1372 float min_dis = m_spellInfo->GetMinRange(true);
1373 float max_dis = m_spellInfo->GetMaxRange(true);
1374 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1375 float x, y, z, angle;
1376 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1377 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1379
1380 float ground = m_caster->GetMapHeight(x, y, z, true);
1381 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1383 if (liquidData.Status)
1384 liquidLevel = liquidData.Level;
1385
1386 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1387 {
1390 finish(false);
1391 return;
1392 }
1393
1394 if (ground + 0.75 > liquidLevel)
1395 {
1398 finish(false);
1399 return;
1400 }
1401
1402 if (!m_caster->IsWithinLOS(x, y, z))
1403 {
1406 finish(false);
1407 return;
1408 }
1409
1410 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1411 break;
1412 }
1414 {
1415 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1416 Map* map = m_caster->GetMap();
1417 uint32 mapid = m_caster->GetMapId();
1418 uint32 phasemask = m_caster->GetPhaseMask();
1419 float collisionHeight = m_caster->GetCollisionHeight();
1420 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1421
1422 Position pos;
1423 Position lastpos;
1424 m_caster->GetPosition(startx, starty, startz, starto);
1425 pos.Relocate(startx, starty, startz, starto);
1426 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1427 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1428
1429 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1430
1431 bool isCasterInWater = m_caster->IsInWater();
1432 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1433 {
1434 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1435 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1436 float maxtravelDistZ = 2.65f;
1437 float overdistance = 0.0f;
1438 float totalpath = 0.0f;
1439 float beforewaterz = 0.0f;
1440 bool inwater = false;
1441 bool wcol = false;
1442 const float step = 2.0f;
1443 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1444 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1445 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1446 int j = 1;
1447 for (; j < (numChecks + 1); j++)
1448 {
1449 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1450 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1451 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1452 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1453
1454 if (j < 2)
1455 {
1456 prevZ = pos.GetPositionZ();
1457 }
1458 else
1459 {
1460 prevZ = tstZ;
1461 }
1462
1463 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1464 ground = tstZ;
1465
1466 if (!isCasterInWater)
1467 {
1468 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1469 {
1470 if (!(beforewaterz != 0.0f))
1471 {
1472 beforewaterz = prevZ;
1473 }
1474 tstZ = beforewaterz;
1475 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1476 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1477 }
1478 }
1479 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1480 {
1481 prevZ = pos.GetPositionZ();
1482 tstZ = pos.GetPositionZ();
1483 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1484
1485 inwater = true;
1486 if (inwater && (fabs(tstZ - ground) < 2.0f))
1487 {
1488 wcol = true;
1489 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1490 }
1491
1492 // if (j < 2)
1493 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1494 // else
1495 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1496 }
1497
1498 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1499 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1500 {
1501 if (inwater && !IsInWater)
1502 inwater = false;
1503
1504 // highest available point
1505 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1506 // upper or floor
1507 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1508 //lower than floor
1509 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1510
1511 //distance of rays, will select the shortest in 3D
1512 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1513 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1514 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1515 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1516 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1517 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1518
1519 if (srange1 < srange2)
1520 {
1521 tstZ = tstZ1;
1522 srange = srange1;
1523 }
1524 else if (srange3 < srange2)
1525 {
1526 tstZ = tstZ3;
1527 srange = srange3;
1528 }
1529 else
1530 {
1531 tstZ = tstZ2;
1532 srange = srange2;
1533 }
1534
1535 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1536 }
1537
1538 destx = tstX;
1539 desty = tstY;
1540 destz = tstZ;
1541
1542 totalpath += srange;
1543
1544 if (totalpath > distance)
1545 {
1546 overdistance = totalpath - distance;
1547 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1548 }
1549
1550 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1551 // check dynamic collision
1552 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1553
1554 // collision occured
1555 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1556 {
1557 if ((overdistance > 0.0f) && (overdistance < 1.f))
1558 {
1559 destx = prevX + overdistance * cos(pos.GetOrientation());
1560 desty = prevY + overdistance * sin(pos.GetOrientation());
1561 //LOG_ERROR("spells", "(collision) collision occured 1");
1562 }
1563 else
1564 {
1565 // move back a bit
1566 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1567 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1568 //LOG_ERROR("spells", "(collision) collision occured 2");
1569 }
1570
1571 // highest available point
1572 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1573 // upper or floor
1574 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1575 //lower than floor
1576 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1577
1578 //distance of rays, will select the shortest in 3D
1579 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1580 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1581 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1582
1583 if (srange1 < srange2)
1584 destz = destz1;
1585 else if (srange3 < srange2)
1586 destz = destz3;
1587 else
1588 destz = destz2;
1589
1590 if (inwater && destz < prevZ && !wcol)
1591 destz = prevZ;
1592 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1593
1594 // Don't make the player move backward from the xy adjustments by collisions.
1595 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1596 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1597 {
1598 destx = startx;
1599 desty = starty;
1600 destz = startz;
1601 }
1602
1603 break;
1604 }
1605 // we have correct destz now
1606 }
1607
1608 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1609 dest = SpellDestination(lastpos);
1610 }
1611 else
1612 {
1613 float z = pos.GetPositionZ();
1614 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1615 // check dynamic collision
1616 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1617
1618 // collision occured
1619 if (col || dcol)
1620 {
1621 // move back a bit
1622 destx = destx - (0.6 * cos(pos.GetOrientation()));
1623 desty = desty - (0.6 * sin(pos.GetOrientation()));
1624 }
1625
1626 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1627 dest = SpellDestination(lastpos);
1628 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1629 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1630 }
1631 break;
1632 }
1633 default:
1634 {
1635 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1636 float angle = targetType.CalcDirectionAngle();
1637 float objSize = m_caster->GetCombatReach();
1638
1639 switch (targetType.GetTarget())
1640 {
1642 dist = PET_FOLLOW_DIST;
1643 break;
1645 if (dist > objSize)
1646 dist = objSize + (dist - objSize) * float(rand_norm());
1647 break;
1652 {
1653 static float const DefaultTotemDistance = 3.0f;
1654 if (!m_spellInfo->Effects[effIndex].HasRadius())
1655 dist = DefaultTotemDistance;
1656 break;
1657 }
1658 default:
1659 break;
1660 }
1661
1662 if (dist < objSize)
1663 {
1664 dist = objSize;
1665 }
1666
1667 Position pos = dest._position;
1668 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1669
1670 dest.Relocate(pos);
1671 break;
1672 }
1673 }
1674
1675 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1676 m_targets.SetDst(dest);
1677}
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
#define MAP_ALL_LIQUIDS
Definition: Map.h:160
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:789
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:783
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1476
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1459
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1448
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1446
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1443
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1447
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1436
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1445
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1440
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1418
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1105
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3120
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2626
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21081
Definition: Map.h:171
float Level
Definition: Map.h:176
LiquidStatus Status
Definition: Map.h:178
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2040
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2201
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2500
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2478
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8695
Definition: SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1756{
1757 WorldObject* target = nullptr;
1758 bool checkIfValid = true;
1759
1760 switch (targetType.GetTarget())
1761 {
1762 case TARGET_UNIT_CASTER:
1763 target = m_caster;
1764 checkIfValid = false;
1765 break;
1766 case TARGET_UNIT_MASTER:
1767 target = m_caster->GetCharmerOrOwner();
1768 break;
1769 case TARGET_UNIT_PET:
1770 target = m_caster->GetGuardianPet();
1771 if (!target)
1772 target = m_caster->GetCharm();
1773 break;
1775 if (m_caster->IsSummon())
1776 target = m_caster->ToTempSummon()->GetSummonerUnit();
1777 break;
1779 target = m_caster->GetVehicleBase();
1780 break;
1790 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1791 break;
1792 default:
1793 break;
1794 }
1795
1796 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1797
1798 if (target && target->ToUnit())
1799 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1800}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1501
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1506
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1507
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1503
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1500
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition: Unit.cpp:18707
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:224

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1825{
1826 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1827 if (Player* modOwner = m_caster->GetSpellModOwner())
1828 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1829
1830 if (maxTargets > 1)
1831 {
1832 // mark damage multipliers as used
1833 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1834 if (effMask & (1 << k))
1835 m_damageMultipliers[k] = 1.0f;
1836 m_applyMultiplierMask |= effMask;
1837
1838 std::list<WorldObject*> targets;
1839 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1840 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1841
1842 // Chain primary target is added earlier
1843 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1844
1845 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1846 if (Unit* unitTarget = (*itr)->ToUnit())
1847 AddUnitTarget(unitTarget, effMask, false);
1848 }
1849}
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:93
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1449
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2194

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1040{
1041 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1042 {
1043 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1044 return;
1045 }
1046
1047 switch (targetType.GetTarget())
1048 {
1050 {
1051 // Xinef: All channel selectors have needed data passed in m_targets structure
1053 if (target)
1054 {
1055 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1056 // unit target may be no longer avalible - teleported out of map for example
1057 if (target && target->ToUnit())
1058 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1059 }
1060 else
1061 {
1062 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1063 }
1064 break;
1065 }
1070 {
1071 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1072 if (target)
1073 m_targets.SetDst(*target);
1074 }
1076 {
1077 if (channeledSpell->m_targets.GetUnitTarget())
1078 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1079 }
1080 else //if (!m_targets.HasDst())
1081 {
1082 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1083 }
1084 break;
1086 if (GetOriginalCaster())
1088 break;
1089 default:
1090 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1091 break;
1092 }
1093}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1480
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1481
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1510
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:463
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:473
bool HasDstChannel() const
Definition: Spell.cpp:468

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1210{
1211 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1212 {
1213 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1214 return;
1215 }
1216 std::list<WorldObject*> targets;
1217 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1218 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1219 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1220 float coneAngle = M_PI / 2;
1221 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1222
1223 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1224 {
1225 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1226 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1227 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1228
1229 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1230
1231 if (!targets.empty())
1232 {
1233 // Other special target selection goes here
1234 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1235 {
1237 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1238 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1239 maxTargets += (*j)->GetAmount();
1240
1241 Acore::Containers::RandomResize(targets, maxTargets);
1242 }
1243
1244 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1245 {
1246 if (Unit* unit = (*itr)->ToUnit())
1247 {
1248 AddUnitTarget(unit, effMask, false);
1249 }
1250 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1251 {
1252 AddGOTarget(gObjTarget, effMask);
1253 }
1254 }
1255 }
1256 }
1257}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1717{
1718 // set destination to caster if no dest provided
1719 // can only happen if previous destination target could not be set for some reason
1720 // (not found nearby target, or channel target for example
1721 // maybe we should abort the spell in such case?
1722 CheckDst();
1723
1725
1726 switch (targetType.GetTarget())
1727 {
1731 case TARGET_DEST_DEST:
1732 return;
1733 case TARGET_DEST_TRAJ:
1734 SelectImplicitTrajTargets(effIndex, targetType);
1735 return;
1736 default:
1737 {
1738 float angle = targetType.CalcDirectionAngle();
1739 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1740 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1741 dist *= float(rand_norm());
1742
1743 Position pos = dest._position;
1744 m_caster->MovePosition(pos, dist, angle);
1745
1746 dest.Relocate(pos);
1747 break;
1748 }
1749 }
1750
1751 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1752 m_targets.ModDst(dest);
1753}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle, bool disableWarning=false)
Definition: Object.cpp:2776
void ModDst(Position const &pos)
Definition: Spell.cpp:435
SpellDestination const * GetDst() const
Definition: Spell.cpp:395

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1096{
1097 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1098 {
1099 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1100 return;
1101 }
1102
1103 float range = 0.0f;
1104 switch (targetType.GetCheckType())
1105 {
1106 case TARGET_CHECK_ENEMY:
1107 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1108 break;
1109 case TARGET_CHECK_ALLY:
1110 case TARGET_CHECK_PARTY:
1111 case TARGET_CHECK_RAID:
1113 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1114 break;
1115 case TARGET_CHECK_ENTRY:
1118 break;
1119 default:
1120 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1121 break;
1122 }
1123
1124 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1125
1126 // handle emergency case - try to use other provided targets if no conditions provided
1127 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1128 {
1129 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1130 switch (targetType.GetObjectType())
1131 {
1134 {
1135 if (focusObject)
1136 AddGOTarget(focusObject, effMask);
1137 return;
1138 }
1139 break;
1142 {
1143 if (focusObject)
1145 return;
1146 }
1147 break;
1148 default:
1149 break;
1150 }
1151 }
1152
1153 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1154 if (!target)
1155 {
1156 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1157 return;
1158 }
1159
1160 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1161 if (!target)
1162 {
1163 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1164 return;
1165 }
1166
1167 switch (targetType.GetObjectType())
1168 {
1170 {
1171 if (Unit* unit = target->ToUnit())
1172 {
1173 AddUnitTarget(unit, effMask, true, false);
1174 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1175 // and if channeled spell has target 77, it requires unitTarget, set it here!
1176 // xinef: if we have NO unit target
1177 if (!m_targets.GetUnitTarget())
1178 {
1180 }
1181 }
1182 else
1183 {
1184 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1185 return;
1186 }
1187 break;
1188 }
1190 if (GameObject* gobjTarget = target->ToGameObject())
1191 AddGOTarget(gobjTarget, effMask);
1192 else
1193 {
1194 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1195 return;
1196 }
1197 break;
1199 m_targets.SetDst(*target);
1200 break;
1201 default:
1202 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1203 break;
1204 }
1205
1206 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1207}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2172
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1824

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1680{
1682
1683 SpellDestination dest(*target);
1684
1685 switch (targetType.GetTarget())
1686 {
1689 break;
1690 default:
1691 {
1692 float angle = targetType.CalcDirectionAngle();
1693 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1694 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1695 {
1696 dist *= float(rand_norm());
1697 }
1698
1699 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1700 {
1702 }
1703
1704 Position pos = dest._position;
1705 target->MovePositionToFirstCollision(pos, dist, angle);
1706
1707 dest.Relocate(pos);
1708 break;
1709 }
1710 }
1711
1712 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1713 m_targets.SetDst(dest);
1714}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1803{
1804 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1805
1807
1808 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1809
1810 if (target)
1811 {
1812 if (Unit* unit = target->ToUnit())
1813 AddUnitTarget(unit, 1 << effIndex, true, false);
1814 else if (GameObject* gobj = target->ToGameObject())
1815 AddGOTarget(gobj, 1 << effIndex);
1816
1817 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1818 }
1819 // Script hook can remove object target and we would wrongly land here
1820 else if (Item* item = m_targets.GetItemTarget())
1821 AddItemTarget(item, 1 << effIndex);
1822}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1866{
1867 if (!m_targets.HasTraj())
1868 return;
1869
1870 float dist2d = m_targets.GetDist2d();
1871 if (!dist2d)
1872 return;
1873
1874 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1875
1876 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1877 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1878 std::list<WorldObject*> targets;
1879 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1881 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1882 if (targets.empty())
1883 return;
1884
1886
1887 float b = tangent(m_targets.GetElevation());
1888 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1889 if (a > -0.0001f)
1890 a = 0;
1891
1892 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1893
1894 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1895 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1896 if (bestDist < 1.0f)
1897 bestDist = 300.0f;
1898
1899 std::list<WorldObject*>::const_iterator itr = targets.begin();
1900 for (; itr != targets.end(); ++itr)
1901 {
1902 if (Unit* unitTarget = (*itr)->ToUnit())
1903 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1904 continue;
1905
1906 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1908 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1909 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1910
1911 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1912 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1913
1914 float dist = objDist2d - size;
1915 float height = dist * (a * dist + b);
1916
1917 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1918
1919 if (dist < bestDist && height < dz + size && height > dz - size)
1920 {
1921 bestDist = dist > 0 ? dist : 0;
1922 break;
1923 }
1924
1925#define CHECK_DIST {\
1926 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1927 if (dist > bestDist)\
1928 continue;\
1929 if (dist < objDist2d + size && dist > objDist2d - size)\
1930 {\
1931 bestDist = dist;\
1932 break;\
1933 }\
1934 }
1935
1936 // RP-GG only, search in straight line, as item have no trajectory
1937 if (m_CastItem)
1938 {
1939 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1940 {
1941 bestDist = dist;
1942 break;
1943 }
1944
1945 continue;
1946 }
1947
1948 if (!a)
1949 {
1950 // Xinef: everything remade
1951 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1952 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1953
1954 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1955 {
1956 bestDist = dist;
1957 break;
1958 }
1959
1960 continue;
1961 }
1962
1963 height = dz - size;
1964 float sqrt1 = b * b + 4 * a * height;
1965 if (sqrt1 > 0)
1966 {
1967 sqrt1 = std::sqrt(sqrt1);
1968 dist = (sqrt1 - b) / (2 * a);
1969 CHECK_DIST;
1970 }
1971
1972 height = dz + size;
1973 float sqrt2 = b * b + 4 * a * height;
1974 if (sqrt2 > 0)
1975 {
1976 sqrt2 = std::sqrt(sqrt2);
1977 dist = (sqrt2 - b) / (2 * a);
1978 CHECK_DIST;
1979
1980 dist = (-sqrt2 - b) / (2 * a);
1981 CHECK_DIST;
1982 }
1983
1984 if (sqrt1 > 0)
1985 {
1986 dist = (-sqrt1 - b) / (2 * a);
1987 CHECK_DIST;
1988 }
1989 }
1990
1992 {
1993 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1994 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
1995 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1996
1997 if (itr != targets.end())
1998 {
1999 float distSq = (*itr)->GetExactDistSq(x, y, z);
2000 float sizeSq = (*itr)->GetObjectSize();
2001 sizeSq *= sizeSq;
2002 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2003 if (distSq > sizeSq)
2004 {
2005 float factor = 1 - std::sqrt(sizeSq / distSq);
2006 x += factor * ((*itr)->GetPositionX() - x);
2007 y += factor * ((*itr)->GetPositionY() - y);
2008 z += factor * ((*itr)->GetPositionZ() - z);
2009
2010 distSq = (*itr)->GetExactDistSq(x, y, z);
2011 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2012 }
2013 }
2014
2015 Position trajDst;
2016 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2018 dest.Relocate(trajDst);
2019
2020 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2021 m_targets.ModDst(dest);
2022 }
2023}
float tangent(float x)
Definition: Spell.cpp:1851
#define CHECK_DIST
Definition: Object.h:696
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1688
float GetElevation() const
Definition: Spell.h:168

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
815{
816 // select targets for cast phase
818
819 uint32 processedAreaEffectsMask = 0;
820 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
821 {
822 // not call for empty effect.
823 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
824 if (!m_spellInfo->Effects[i].IsEffect())
825 continue;
826
827 // set expected type of implicit targets to be sent to client
828 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
829 if (implicitTargetMask & TARGET_FLAG_UNIT)
831 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
833
834 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
835 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
836
837 // Select targets of effect based on effect type
838 // those are used when no valid target could be added for spell effect based on spell target type
839 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
840 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
841 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
843
844 if (m_targets.HasDst())
846
848 {
849 // maybe do this for all spells?
850 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
851 {
853 finish(false);
854 return;
855 }
856
857 uint8 mask = (1 << i);
858 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
859 {
860 if (ihit->effectMask & mask)
861 {
863 break;
864 }
865 }
866 }
867 else if (m_auraScaleMask)
868 {
869 bool checkLvl = !m_UniqueTargetInfo.empty();
870 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
871 {
872 // remove targets which did not pass min level check
873 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
874 {
875 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
876 return true;
877 }
878
879 return false;
880 }), std::end(m_UniqueTargetInfo));
881
882 if (checkLvl && m_UniqueTargetInfo.empty())
883 {
885 finish(false);
886 }
887 }
888 }
889
890 if (uint64 dstDelay = CalculateDelayMomentForDst())
891 m_delayMoment = dstDelay;
892}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:30
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:120
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:921
void SelectExplicitTargets()
Definition: Spell.cpp:781
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2603
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2025

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4668{
4669 if (result == SPELL_CAST_OK)
4670 return;
4671
4672 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4673 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4674
4675 caster->GetSession()->SendPacket(&data);
4676}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4562

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4679{
4680 if (result == SPELL_CAST_OK)
4681 return;
4682
4683 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4684 return;
4685
4686 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4687 return;
4688
4689 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4691 result = SPELL_FAILED_DONT_REPORT;
4692
4694}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:146
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
bool IsCharmed() const
Definition: Unit.h:1278

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5205{
5206 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5207 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5208 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5209 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5210
5211 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5212 data << m_caster->GetPackGUID();
5213 data << uint32(m_spellInfo->Id);
5214 data << uint32(duration);
5215
5216 m_caster->SendMessageToSet(&data, true);
5217
5220
5221 m_timer = duration;
5222 if (channelTarget)
5224
5226}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5173{
5174 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5175 data << m_caster->GetPackGUID();
5176 data << uint8(m_cast_count);
5177 data << uint32(m_spellInfo->Id);
5178 data << uint8(result);
5179 m_caster->SendMessageToSet(&data, true);
5180
5181 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5182 data << m_caster->GetPackGUID();
5183 data << uint8(m_cast_count);
5184 data << uint32(m_spellInfo->Id);
5185 data << uint8(result);
5186 m_caster->SendMessageToSet(&data, true);
5187}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5072{
5073 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5074
5075 data << m_caster->GetPackGUID();
5076
5077 data << uint32(m_spellInfo->Id);
5078
5079 uint8 effCount = 0;
5080 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5081 {
5082 if (m_effectExecuteData[i])
5083 ++effCount;
5084 }
5085
5086 if (!effCount)
5087 return;
5088
5089 data << uint32(effCount);
5090 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5091 {
5092 if (!m_effectExecuteData[i])
5093 continue;
5094
5095 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5096
5097 data.append(*m_effectExecuteData[i]);
5098
5099 delete m_effectExecuteData[i];
5100 m_effectExecuteData[i] = nullptr;
5101 }
5102 m_caster->SendMessageToSet(&data, true);
5103}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
1995{
1996 Player* player = m_caster->ToPlayer();
1997 if (!player)
1998 return;
1999
2000 if (gameObjTarget)
2001 {
2002 // Players shouldn't be able to loot gameobjects that are currently despawned
2003 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2004 {
2005 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2006 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2007 return;
2008 }
2009 // special case, already has GossipHello inside so return and avoid calling twice
2011 {
2013 return;
2014 }
2015
2016 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2017 return;
2018
2019 if (gameObjTarget->AI()->GossipHello(player, false))
2020 return;
2021
2022 switch (gameObjTarget->GetGoType())
2023 {
2025 gameObjTarget->UseDoorOrButton(0, false, player);
2026 return;
2028 gameObjTarget->UseDoorOrButton(0, false, player);
2029
2030 // Xinef: properly link possible traps
2031 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2032 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2033 return;
2037 return;
2038
2040 // triggering linked GO
2043 return;
2044
2046 // triggering linked GO
2047 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2049
2050 // Don't return, let loots been taken
2051 default:
2052 break;
2053 }
2054 }
2055
2056 // Send loot
2057 player->SendLoot(guid, loottype);
2058}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:54
bool isSpawned() const
Definition: GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1385
uint32 gossipID
Definition: GameObjectData.h:72
uint32 linkedTrap
Definition: GameObjectData.h:59
struct GameObjectTemplate::@227::@232 chest
struct GameObjectTemplate::@227::@236 spellFocus
uint32 linkedTrapId
Definition: GameObjectData.h:90
struct GameObjectTemplate::@227::@231 questgiver
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4697{
4698 if (result == SPELL_CAST_OK)
4699 return;
4700
4701 Unit* owner = m_caster->GetCharmerOrOwner();
4702 if (!owner)
4703 return;
4704
4705 Player* player = owner->ToPlayer();
4706 if (!player)
4707 return;
4708
4709 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4711
4712 player->GetSession()->SendPacket(&data);
4713}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5229{
5230 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5231 // for player resurrections the name is looked up by guid
5232 std::string const sentName(m_caster->IsPlayer()
5233 ? ""
5235
5236 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5237 data << m_caster->GetGUID();
5238 data << uint32(sentName.size() + 1);
5239
5240 data << sentName;
5241 data << uint8(0); // null terminator
5242
5243 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5244 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5246 data << uint32(0);
5247 target->GetSession()->SendPacket(&data);
5248}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:461
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4354{
4355 // xinef: properly add creature cooldowns
4356 if (!m_caster->IsPlayer())
4357 {
4359 {
4360 // xinef: this should be added here
4361 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4362
4363 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4366 {
4367 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4368 data << m_caster->GetGUID();
4370 data << uint32(m_spellInfo->Id);
4372 player->SendDirectMessage(&data);
4373 }
4374 }
4375 return;
4376 }
4377
4378 Player* _player = m_caster->ToPlayer();
4379
4380 // mana/health/etc potions, disabled by client (until combat out as declarate)
4382 {
4383 // need in some way provided data for Spell::finish SendCooldownEvent
4384 _player->SetLastPotionId(m_CastItem->GetEntry());
4385 return;
4386 }
4387
4388 // have infinity cooldown but set at aura apply
4389 // do not set cooldown for triggered spells (needed by reincarnation)
4394 return;
4395
4397}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:617
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1795
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10907
uint32 RecoveryTime
Definition: SpellInfo.h:348
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1181

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4796{
4797 // not send invisible spell casting
4798 if (!IsNeedSendToClient(true))
4799 return;
4800
4801 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4802
4803 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4804
4805 // triggered spells with spell visual != 0
4807 castFlags |= CAST_FLAG_PENDING;
4808
4810 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4811
4812 // should only be sent to self, but the current messaging doesn't make that possible
4813 if (m_caster->IsPlayer() || m_caster->IsPet())
4814 {
4815 switch (m_spellInfo->PowerType)
4816 {
4817 case POWER_HEALTH:
4818 break;
4819 case POWER_RUNE:
4820 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4821 break;
4822 default:
4823 if (m_powerCost != 0)
4824 {
4825 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4826 }
4827 break;
4828 }
4829 }
4830
4831 if ((m_caster->IsPlayer())
4835 {
4836 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4837 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4838 }
4839
4841 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4842
4843 if (m_targets.HasTraj())
4844 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4845
4847 castFlags |= CAST_FLAG_NO_GCD;
4848
4849 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4850 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4851 {
4852 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4853 {
4854 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4855 {
4856 realCasterGUID = casterGameobject->GetPackGUID();
4857 }
4858 }
4859 }
4860
4861 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4862
4863 if (m_CastItem)
4864 data << m_CastItem->GetPackGUID();
4865 else
4866 data << realCasterGUID;
4867
4868 data << realCasterGUID;
4869 data << uint8(m_cast_count); // pending spell cast?
4870 data << uint32(m_spellInfo->Id); // spellId
4871 data << uint32(castFlags); // cast flags
4872 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4873
4874 WriteSpellGoTargets(&data);
4875
4876 m_targets.Write(data);
4877
4878 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4880
4881 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4882 {
4883 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4884 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4885 if (Player* player = m_caster->ToPlayer())
4886 {
4887 uint8 runeMaskInitial = m_runesState;
4888 uint8 runeMaskAfterCast = player->GetRunesState();
4889 data << uint8(runeMaskInitial); // runes state before
4890 data << uint8(runeMaskAfterCast); // runes state after
4891 for (uint8 i = 0; i < MAX_RUNES; ++i)
4892 {
4893 uint8 mask = (1 << i);
4894 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4895 {
4896 // float casts ensure the division is performed on floats as we need float result
4897 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4898 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4899 }
4900 }
4901 }
4902 }
4903 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4904 {
4905 data << m_targets.GetElevation();
4907 }
4908
4909 if (castFlags & CAST_FLAG_PROJECTILE)
4910 WriteAmmoToPacket(&data);
4911
4912 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4913 {
4914 data << uint32(0);
4915 data << uint32(0);
4916 }
4917
4919 {
4920 data << uint8(0);
4921 }
4922
4923 m_caster->SendMessageToSet(&data, true);
4924}
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:63
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:61
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:52
@ CAST_FLAG_NO_GCD
Definition: Spell.h:62
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:49
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:55
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:65
@ CAST_FLAG_PENDING
Definition: Spell.h:44
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:924
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition: Spell.cpp:178
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:5011
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4926
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8089
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:347
int32 CastTime
Definition: DBCStructure.h:1759

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4716{
4717 if (!IsNeedSendToClient(false))
4718 return;
4719
4720 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4721
4722 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4723
4725 castFlags |= CAST_FLAG_PENDING;
4726
4728 castFlags |= CAST_FLAG_PROJECTILE;
4729
4730 if (m_caster->IsPlayer() || m_caster->IsPet())
4731 {
4732 switch (m_spellInfo->PowerType)
4733 {
4734 case POWER_HEALTH:
4735 break;
4736 case POWER_RUNE:
4737 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4738 break;
4739 default:
4740 if (m_powerCost != 0)
4741 {
4742 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4743 }
4744 break;
4745 }
4746 }
4747
4749 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4750
4751 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4752 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4753 {
4754 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4755 {
4756 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4757 {
4758 realCasterGUID = casterGameobject->GetPackGUID();
4759 }
4760 }
4761 }
4762
4763 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4764 if (m_CastItem)
4765 data << m_CastItem->GetPackGUID();
4766 else
4767 data << realCasterGUID;
4768
4769 data << realCasterGUID;
4770 data << uint8(m_cast_count); // pending spell cast?
4771 data << uint32(m_spellInfo->Id); // spellId
4772 data << uint32(castFlags); // cast flags
4773 data << int32(m_timer); // delay?
4774
4775 m_targets.Write(data);
4776
4777 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4779
4780 if (castFlags & CAST_FLAG_PROJECTILE)
4781 WriteAmmoToPacket(&data);
4782
4783 if (castFlags & CAST_FLAG_UNKNOWN_23)
4784 {
4785 data << uint32(0);
4786 data << uint32(0);
4787 }
4788
4789 m_caster->SendMessageToSet(&data, true);
4790
4793}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
549{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
563{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
561{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8431{
8432 switch (mod)
8433 {
8435 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8436 break;
8438 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8439 break;
8441 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8442 break;
8444 m_spellValue->RadiusMod = (float)value / 10000;
8445 break;
8448 break;
8451 break;
8453 m_spellValue->AuraDuration = value;
8454 break;
8456 m_spellValue->ForcedCritResult = (bool)value;
8457 break;
8458 }
8459}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:118
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:119
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:120
bool ForcedCritResult
Definition: Spell.h:218

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
483{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5930{
5931 Unit* caster = m_originalCaster;
5932 if (!caster)
5933 return;
5934
5935 if (caster->IsTotem())
5936 caster = caster->ToTotem()->GetOwner();
5937
5938 // in another case summon new
5939 uint8 summonLevel = caster->GetLevel();
5940
5941 // level of pet summoned using engineering item based at engineering skill level
5942 if (m_CastItem && caster->IsPlayer())
5943 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5944 {
5945 // xinef: few special cases
5946 if (proto->RequiredSkill == SKILL_ENGINEERING)
5947 {
5948 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5949 summonLevel = skill202 / 5;
5950 }
5951
5952 switch (m_spellInfo->Id)
5953 {
5954 // Dragon's Call
5955 case 13049:
5956 summonLevel = 55;
5957 break;
5958
5959 // Cleansed Timberling Heart: Summon Timberling
5960 case 5666:
5961 summonLevel = 7;
5962 break;
5963
5964 // Glowing Cat Figurine: Summon Ghost Saber
5965 case 6084:
5966 // minLevel 19, maxLevel 20
5967 summonLevel = 20;
5968 break;
5969
5970 // Spiked Collar: Summon Felhunter
5971 case 8176:
5972 summonLevel = 30;
5973 break;
5974
5975 // Dog Whistle: Summon Tracking Hound
5976 case 9515:
5977 summonLevel = 30;
5978 break;
5979
5980 // Barov Peasant Caller: Death by Peasant
5981 case 18307:
5982 case 18308:
5983 summonLevel = 60;
5984 break;
5985
5986 // Thornling Seed: Plant Thornling
5987 case 22792:
5988 summonLevel = 60;
5989 break;
5990
5991 // Cannonball Runner: Summon Crimson Cannon
5992 case 6251:
5993 summonLevel = 61;
5994 break;
5995 }
5996 }
5997
5998 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
5999
6000 float radius = 5.0f;
6001 int32 duration = m_spellInfo->GetDuration();
6002
6003 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6004 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6005
6006 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6007 Map* map = caster->GetMap();
6008 TempSummon* summon = nullptr;
6009
6010 uint32 currMinionsCount = m_caster->m_Controlled.size();
6011 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6012
6013 for (uint32 count = 0; count < numGuardians; ++count)
6014 {
6015 Position pos;
6016
6017 // xinef: do not use precalculated position for effect summon pet in this function
6018 // it means it was cast by NPC and should have its position overridden unless the
6019 // target position is specified in the DB AND the effect has no or zero radius
6020 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6021 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6022 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6023 {
6024 pos = *destTarget;
6025 }
6026 else
6027 {
6028 // randomize position
6029 pos = m_caster->GetRandomPoint(*destTarget, radius);
6030 }
6031
6032 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6033 if (!summon)
6034 return;
6035
6036 // xinef: set calculated level
6037 summon->SetLevel(summonLevel);
6038
6039 // if summonLevel changed, set stats for calculated level
6040 if (summonLevel != caster->GetLevel())
6041 {
6042 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6043 }
6044
6045 // xinef: if we have more than one guardian, change follow angle
6046 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6047 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6048 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6049 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6050
6051 // xinef: move this here, some auras are added in initstatsforlevel!
6052 if (!summon->IsInCombat() && !summon->IsTrigger())
6053 {
6054 // summon->AI()->EnterEvadeMode();
6055 summon->GetMotionMaster()->Clear(false);
6057 }
6058
6059 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6060 summon->SetFaction(caster->GetFaction());
6061
6063 }
6064}
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:235
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:285
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
bool IsTrigger() const
Definition: Creature.h:78
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15424

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5378{
5380 {
5382
5383 // wands don't have ammo
5384 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5385 return;
5386
5387 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5388 {
5389 if (pItem->GetMaxStackCount() == 1)
5390 {
5391 // decrease durability for non-stackable throw weapon
5393 }
5394 else
5395 {
5396 // decrease items amount for stackable throw weapon
5397 uint32 count = 1;
5398 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5399 }
5400 }
5402 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5403 }
5404}
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
@ INVTYPE_THROWN
Definition: ItemTemplate.h:281
uint32 GetMaxStackCount() const
Definition: Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4804

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, and Object::ToPlayer().

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5251{
5252 if (!m_CastItem || !m_caster->IsPlayer())
5253 return;
5254
5255 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5257 return;
5258
5259 ItemTemplate const* proto = m_CastItem->GetTemplate();
5260
5261 if (!proto)
5262 {
5263 // This code is to avoid a crash
5264 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5265 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5266 return;
5267 }
5268
5269 bool expendable = false;
5270 bool withoutCharges = false;
5271
5272 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5273 {
5274 if (proto->Spells[i].SpellId)
5275 {
5276 // item has limited charges
5277 if (proto->Spells[i].SpellCharges)
5278 {
5279 if (proto->Spells[i].SpellCharges < 0)
5280 expendable = true;
5281
5282 int32 charges = m_CastItem->GetSpellCharges(i);
5283
5284 // item has charges left
5285 if (charges)
5286 {
5287 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5288 if (proto->Stackable == 1)
5289 m_CastItem->SetSpellCharges(i, charges);
5291 }
5292
5293 // all charges used
5294 withoutCharges = (charges == 0);
5295 }
5296 }
5297 }
5298
5299 if (expendable && withoutCharges)
5300 {
5301 uint32 count = 1;
5302 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5303
5304 // prevent crash at access to deleted m_targets.GetItemTarget
5306 m_targets.SetItemTarget(nullptr);
5307
5308 m_CastItem = nullptr;
5310 }
5311}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:318
int32 Stackable
Definition: ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5314{
5316 return;
5317
5318 //Don't take power if the spell is cast while .cheat power is enabled.
5319 if (m_caster->IsPlayer())
5321 return;
5322
5324 bool hit = true;
5325 if (m_caster->IsPlayer())
5326 {
5328 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5329 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5330 if (ihit->targetGUID == targetGUID)
5331 {
5332 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5333 {
5334 hit = false;
5335 //lower spell cost on fail (by talent aura)
5336 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5337 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5338 }
5339 break;
5340 }
5341 }
5342
5343 if (PowerType == POWER_RUNE)
5344 {
5345 TakeRunePower(hit);
5346 return;
5347 }
5348
5349 if (!m_powerCost)
5350 return;
5351
5352 // health as power used
5353 if (PowerType == POWER_HEALTH)
5354 {
5356 return;
5357 }
5358
5359 if (PowerType >= MAX_POWERS)
5360 {
5361 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5362 return;
5363 }
5364
5365 if (hit)
5367 else
5369
5370 // Set the five second timer
5371 if (PowerType == POWER_MANA && m_powerCost > 0)
5372 {
5374 }
5375}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:106
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14055
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:1570
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5460

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5530{
5531 if (!m_caster->IsPlayer())
5532 return;
5533
5534 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5535
5536 // do not take reagents for these item casts
5537 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5538 return;
5539
5540 Player* p_caster = m_caster->ToPlayer();
5541 if (p_caster->CanNoReagentCast(m_spellInfo))
5542 return;
5543
5544 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5545 {
5546 if (m_spellInfo->Reagent[x] <= 0)
5547 continue;
5548
5549 uint32 itemid = m_spellInfo->Reagent[x];
5550 uint32 itemcount = m_spellInfo->ReagentCount[x];
5551
5552 // if CastItem is also spell reagent
5553 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5554 {
5555 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5556 {
5557 // CastItem will be used up and does not count as reagent
5558 int32 charges = m_CastItem->GetSpellCharges(s);
5559 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5560 {
5561 ++itemcount;
5562 break;
5563 }
5564 }
5565
5566 m_CastItem = nullptr;
5568 }
5569
5570 // if GetItemTarget is also spell reagent
5571 if (m_targets.GetItemTargetEntry() == itemid)
5572 m_targets.SetItemTarget(nullptr);
5573
5574 p_caster->DestroyItemCount(itemid, itemcount, true);
5575 }
5576}
uint32 ItemId
Definition: ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5461{
5463 return;
5464
5465 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5466 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5467 return;
5468
5469 Player* player = m_caster->ToPlayer();
5470 m_runesState = player->GetRunesState(); // store previous state
5471
5472 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5473
5474 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5475 {
5476 runeCost[i] = runeCostData->RuneCost[i];
5477 if (Player* modOwner = m_caster->GetSpellModOwner())
5478 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5479 }
5480
5481 runeCost[RUNE_DEATH] = 0; // calculated later
5482
5483 for (uint32 i = 0; i < MAX_RUNES; ++i)
5484 {
5485 RuneType rune = player->GetCurrentRune(i);
5486 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5487 {
5488 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5489 player->SetLastUsedRune(rune);
5490 runeCost[rune]--;
5491 }
5492 }
5493
5494 // Xinef: firstly consume death runes of base type
5495 // Xinef: in second loop consume all available
5496 for (uint8 loop = 0; loop < 2; ++loop)
5497 {
5498 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5499 if (runeCost[RUNE_DEATH] > 0)
5500 {
5501 for (uint8 i = 0; i < MAX_RUNES; ++i)
5502 {
5503 RuneType rune = player->GetCurrentRune(i);
5504 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5505 {
5506 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5507 player->SetLastUsedRune(rune);
5508 runeCost[rune]--;
5509 if (!loop)
5510 runeCost[player->GetBaseRune(i)]--;
5511
5512 // keep Death Rune type if missed
5513 if (didHit)
5514 player->RestoreBaseRune(i);
5515
5516 if (runeCost[RUNE_DEATH] == 0)
5517 break;
5518 }
5519 }
5520 }
5521 }
5522
5523 // you can gain some runic power when use runes
5524 if (didHit)
5525 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5526 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5527}
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:432
@ RUNE_UNHOLY
Definition: Player.h:410
@ RUNE_BLOOD
Definition: Player.h:409
@ RUNE_MISS_COOLDOWN
Definition: Player.h:404
void SetLastUsedRune(RuneType type)
Definition: Player.h:2495
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13371
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13400
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1810
uint32 runePowerGain
Definition: DBCStructure.h:1807

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8839{
8841 if (!gcd)
8842 {
8843 // Xinef: fix for charmed pet spells with no cooldown info
8845 gcd = MIN_GCD;
8846 else
8847 return;
8848 }
8849
8850 if (m_caster->IsPlayer())
8852 return;
8853
8854 // Global cooldown can't leave range 1..1.5 secs
8855 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8856 // but as tests show are not affected by any spell mods.
8858 {
8859 // gcd modifier auras are applied only to own spells and only players have such mods
8860 if (m_caster->IsPlayer())
8862
8863 // Apply haste rating
8866 {
8867 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8868 }
8869
8870 if (gcd < MIN_GCD)
8871 gcd = MIN_GCD;
8872 else if (gcd > MAX_GCD)
8873 gcd = MAX_GCD;
8874 }
8875
8876 // Only players or controlled units have global cooldown
8877 if (m_caster->GetCharmInfo())
8879 else if (m_caster->IsPlayer())
8881}
@ MIN_GCD
Definition: Spell.cpp:8823
@ MAX_GCD
Definition: Spell.cpp:8824
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:97
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:411

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4400{
4401 // update pointers based at it's GUIDs
4402 if (!UpdatePointers())
4403 {
4404 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4405 cancel();
4406 return;
4407 }
4408
4410 {
4411 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4412 cancel();
4413 return;
4414 }
4415
4416 // check if the player caster has moved before the spell finished
4417 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4418 if ((m_caster->IsPlayer() && m_timer != 0) &&
4421 {
4422 // don't cancel for melee, autorepeat, triggered and instant spells
4424 cancel(true);
4425 }
4426
4427 switch (m_spellState)
4428 {
4430 {
4431 if (m_timer > 0)
4432 {
4433 if (difftime >= (uint32)m_timer)
4434 m_timer = 0;
4435 else
4436 m_timer -= difftime;
4437 }
4438
4439 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4440 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4441 cast(!m_casttime);
4442 break;
4443 }
4445 {
4446 if (m_timer)
4447 {
4448 if (m_timer > 0)
4449 {
4450 if (difftime >= (uint32)m_timer)
4451 m_timer = 0;
4452 else
4453 m_timer -= difftime;
4454 }
4455 }
4456
4457 if (m_timer == 0)
4458 {
4460
4461 finish();
4462 }
4463 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4464 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4465 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4466 // Xinef: so the aura can be removed in different updates for all units
4467 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4468 {
4469 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4471 finish();
4472 }
4473 break;
4474 }
4475 default:
4476 break;
4477 }
4478}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3387

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3388{
3389 // Not need check return true
3391 return true;
3392
3393 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3394 uint8 channelAuraMask = 0;
3395 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3397 channelAuraMask |= 1 << i;
3398
3399 channelAuraMask &= channelTargetEffectMask;
3400
3401 float range = 0;
3402 if (channelAuraMask)
3403 {
3405 if (range == 0)
3406 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3407 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3408 {
3409 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3410 break;
3411 }
3412
3413 if (Player* modOwner = m_caster->GetSpellModOwner())
3414 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3415
3416 // xinef: add little tolerance level
3417 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3418 }
3419
3420 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3421 {
3422 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3423 {
3424 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3425
3426 if (!unit)
3427 continue;
3428
3429 if (IsValidDeadOrAliveTarget(unit))
3430 {
3431 if (channelAuraMask & ihit->effectMask)
3432 {
3434 {
3435 if (m_caster != unit)
3436 {
3437 if (!m_caster->IsWithinDistInMap(unit, range))
3438 {
3439 ihit->effectMask &= ~aurApp->GetEffectMask();
3440 unit->RemoveAura(aurApp);
3441 continue;
3442 }
3443 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3446 }
3447 }
3448 else // aura is dispelled
3449 continue;
3450 }
3451
3452 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3453 }
3454 }
3455 }
3456
3457 // Xinef: not all effects are covered, remove applications from all targets
3458 if (channelTargetEffectMask != 0)
3459 {
3460 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3461 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3462 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3463 if (IsValidDeadOrAliveTarget(unit))
3465 {
3466 ihit->effectMask &= ~aurApp->GetEffectMask();
3467 unit->RemoveAura(aurApp);
3468 }
3469 }
3470
3471 // is all effects from m_needAliveTargetMask have alive targets
3472 return channelTargetEffectMask == 0;
3473}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:433
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5540
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20040
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8221

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7860{
7863 else
7864 {
7867 m_originalCaster = nullptr;
7868 }
7869
7871 {
7873 // cast item not found, somehow the item is no longer where we expected
7874 if (!m_CastItem)
7875 return false;
7876 }
7877 else
7878 m_CastItem = nullptr;
7879
7881
7882 // further actions done only for dest targets
7883 if (!m_targets.HasDst())
7884 return true;
7885
7886 // cache last transport
7887 WorldObject* transport = nullptr;
7888
7889 // update effect destinations (in case of moved transport dest target)
7890 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7891 {
7892 SpellDestination& dest = m_destTargets[effIndex];
7893 if (!dest._transportGUID)
7894 continue;
7895
7896 if (!transport || transport->GetGUID() != dest._transportGUID)
7898
7899 if (transport)
7900 {
7901 dest._position.Relocate(transport);
7903 }
7904 }
7905
7906 return true;
7907}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition: Position.cpp:58
Position _transportOffset
Definition: Spell.h:105
ObjectGuid _transportGUID
Definition: Spell.h:104
void Update(Unit *caster)
Definition: Spell.cpp:478

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4927{
4928 uint32 ammoInventoryType = 0;
4929 uint32 ammoDisplayID = 0;
4930
4931 if (m_caster->IsPlayer())
4932 {
4934 if (pItem)
4935 {
4936 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4937 if (ammoInventoryType == INVTYPE_THROWN)
4938 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4939 else
4940 {
4942 if (ammoID)
4943 {
4944 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4945 if (pProto)
4946 {
4947 ammoDisplayID = pProto->DisplayInfoID;
4948 ammoInventoryType = pProto->InventoryType;
4949 }
4950 }
4951 else if (m_caster->HasAura(46699)) // Requires No Ammo
4952 {
4953 ammoDisplayID = 5996; // normal arrow
4954 ammoInventoryType = INVTYPE_AMMO;
4955 }
4956 }
4957 }
4958 }
4959 else
4960 {
4961 uint32 nonRangedAmmoDisplayID = 0;
4962 uint32 nonRangedAmmoInventoryType = 0;
4963 for (uint8 i = 0; i < 3; ++i)
4964 {
4966 {
4967 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4968 {
4969 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4970 {
4971 switch (itemEntry->SubclassID)
4972 {
4974 ammoDisplayID = itemEntry->DisplayInfoID;
4975 ammoInventoryType = itemEntry->InventoryType;
4976 break;
4979 ammoDisplayID = 5996; // is this need fixing?
4980 ammoInventoryType = INVTYPE_AMMO;
4981 break;
4983 ammoDisplayID = 5998; // is this need fixing?
4984 ammoInventoryType = INVTYPE_AMMO;
4985 break;
4986 default:
4987 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4988 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4989 break;
4990 }
4991
4992 if (ammoDisplayID)
4993 break;
4994 }
4995 }
4996 }
4997 }
4998
4999 if (!ammoDisplayID && !ammoInventoryType)
5000 {
5001 ammoDisplayID = nonRangedAmmoDisplayID;
5002 ammoInventoryType = nonRangedAmmoInventoryType;
5003 }
5004 }
5005
5006 *data << uint32(ammoDisplayID);
5007 *data << uint32(ammoInventoryType);
5008}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
@ INVTYPE_AMMO
Definition: ItemTemplate.h:280
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
Definition: DBCStructure.h:1139

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4563{
4564 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4565 data << uint32(spellInfo->Id);
4566 data << uint8(result); // problem
4567 switch (result)
4568 {
4570 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4571 break;
4572 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4573 // hardcode areas limitation case
4574 switch (spellInfo->Id)
4575 {
4576 case 41617: // Cenarion Mana Salve
4577 case 41619: // Cenarion Healing Salve
4578 data << uint32(3905);
4579 break;
4580 case 41618: // Bottled Nethergon Energy
4581 case 41620: // Bottled Nethergon Vapor
4582 data << uint32(3842);
4583 break;
4584 case 45373: // Bloodberry Elixir
4585 data << uint32(4075);
4586 break;
4587 default: // default case (don't must be)
4588 data << uint32(0);
4589 break;
4590 }
4591 break;
4593 if (spellInfo->Totem[0])
4594 data << uint32(spellInfo->Totem[0]);
4595 if (spellInfo->Totem[1])
4596 data << uint32(spellInfo->Totem[1]);
4597 break;
4599 if (spellInfo->TotemCategory[0])
4600 data << uint32(spellInfo->TotemCategory[0]);
4601 if (spellInfo->TotemCategory[1])
4602 data << uint32(spellInfo->TotemCategory[1]);
4603 break;
4607 data << uint32(spellInfo->EquippedItemClass);
4608 data << uint32(spellInfo->EquippedItemSubClassMask);
4609 break;
4611 {
4612 uint32 item = 0;
4613 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4614 if (spellInfo->Effects[eff].ItemType)
4615 item = spellInfo->Effects[eff].ItemType;
4616 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4617 if (proto && proto->ItemLimitCategory)
4618 data << uint32(proto->ItemLimitCategory);
4619 break;
4620 }
4622 data << uint32(customError);
4623 break;
4625 {
4626 uint32 missingItem = 0;
4627 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4628 {
4629 if (spellInfo->Reagent[i] <= 0)
4630 continue;
4631
4632 uint32 itemid = spellInfo->Reagent[i];
4633 uint32 itemcount = spellInfo->ReagentCount[i];
4634
4635 if (!caster->HasItemCount(itemid, itemcount))
4636 {
4637 missingItem = itemid;
4638 break;
4639 }
4640 }
4641
4642 data << uint32(missingItem); // first missing item
4643 break;
4644 }
4646 data << uint32(spellInfo->Mechanic);
4647 break;
4649 data << uint32(spellInfo->EquippedItemSubClassMask);
4650 break;
4652 data << uint32(0); // Item entry
4653 data << uint32(0); // Count
4654 break;
4656 data << uint32(0); // SkillLine.dbc Id
4657 data << uint32(0); // Amount
4658 break;
4660 data << uint32(0); // Skill level
4661 break;
4662 default:
4663 break;
4664 }
4665}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:1003
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1130
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1099
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1096
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1050

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5012{
5013 // This function also fill data for channeled spells:
5014 // m_needAliveTargetMask req for stop channelig if one target die
5015 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5016 {
5017 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5018 // possibly SPELL_MISS_IMMUNE2 for this??
5019 ihit->missCondition = SPELL_MISS_IMMUNE2;
5020 }
5021
5022 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5023 // sending more than 255 targets crashes the client (since count sent would be wrong)
5024 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5025 // target conditions but we still need to limit the number of targets sent and keeping
5026 // correct count for both hit and miss).
5027
5028 uint32 hit = 0;
5029 std::size_t hitPos = data->wpos();
5030 *data << (uint8)0; // placeholder
5031 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5032 {
5033 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5034 {
5035 *data << ihit->targetGUID;
5036 // Xinef: No channeled spell checked, no anything
5037 //m_channelTargetEffectMask |=ihit->effectMask;
5038 ++hit;
5039 }
5040 }
5041
5042 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5043 {
5044 *data << ighit->targetGUID; // Always hits
5045 ++hit;
5046 }
5047
5048 uint32 miss = 0;
5049 std::size_t missPos = data->wpos();
5050 *data << (uint8)0; // placeholder
5051 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5052 {
5053 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5054 {
5055 *data << ihit->targetGUID;
5056 *data << uint8(ihit->missCondition);
5057 if (ihit->missCondition == SPELL_MISS_REFLECT)
5058 *data << uint8(ihit->reflectResult);
5059 ++miss;
5060 }
5061 }
5062 // Reset m_needAliveTargetMask for non channeled spell
5063 // Xinef: Why do we reset something that is not set??????
5064 //if (!m_spellInfo->IsChanneled())
5065 // m_channelTargetEffectMask = 0;
5066
5067 data->put<uint8>(hitPos, (uint8)hit);
5068 data->put<uint8>(missPos, (uint8)miss);
5069}
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().